重构语法树/符号表

This commit is contained in:
csh
2025-10-15 20:31:00 +08:00
parent f52768e385
commit 1f7045140e
113 changed files with 229450 additions and 221041 deletions
@@ -0,0 +1,160 @@
#include "./builder.hpp"
#include "../collector/symbol_collector.hpp"
#include "../collector/incremental_collector.hpp"
#include "../incremental/incremental_engine.hpp"
namespace lsp::language::symbol
{
// ==================== 构造和析构 ====================
SymbolTableBuilder::SymbolTableBuilder() :
incremental_enabled_(false)
{
}
SymbolTableBuilder::~SymbolTableBuilder() = default;
// ==================== 构建接口 ====================
bool SymbolTableBuilder::Build(const std::vector<ast::ASTNode>& nodes)
{
// 清空错误
error_reporter_.Clear();
// 初始化统计信息
stats_ = BuildStatistics{};
stats_.is_incremental = false;
stats_.total_symbols = nodes.size();
// 创建收集上下文
CollectorContext context(registry_, error_reporter_);
// 创建基础收集器并执行
SymbolCollector collector(context);
bool success = collector.Collect(nodes);
// 更新统计信息
stats_.success = success && !error_reporter_.HasErrors();
stats_.new_symbols = stats_.total_symbols;
stats_.reused_symbols = 0;
stats_.reuse_rate = 0.0;
// 完整构建后,如果启用增量,则构建缓存
if (stats_.success && incremental_enabled_ && incremental_engine_)
{
incremental_engine_->BuildCache(registry_);
}
return stats_.success;
}
bool SymbolTableBuilder::BuildIncremental(
const ast::IncrementalParseResult& parse_result)
{
// 检查增量是否启用
if (!incremental_enabled_ || !incremental_engine_)
{
// 增量未启用,退回完整构建
return Build(parse_result.result.nodes);
}
// 清空错误
error_reporter_.Clear();
// 初始化统计信息
stats_ = BuildStatistics{};
stats_.is_incremental = true;
stats_.total_symbols = parse_result.result.nodes.size();
// 创建收集上下文
CollectorContext context(registry_, error_reporter_);
// 创建增量收集器并执行
IncrementalCollector collector(context, *incremental_engine_);
bool success = collector.CollectIncremental(parse_result);
// 更新统计信息
stats_.reused_symbols = collector.GetReusedCount();
stats_.new_symbols = collector.GetNewCount();
// 修复:防止除零
if (stats_.total_symbols > 0)
{
stats_.reuse_rate = static_cast<double>(stats_.reused_symbols) / stats_.total_symbols;
}
else
{
stats_.reuse_rate = 0.0;
}
stats_.success = success && !error_reporter_.HasErrors();
// 检查缓存大小,必要时进行清理
if (incremental_engine_->GetCacheSize() > 10000) // 可配置
{
// LRU 会自动处理,这里只是检查
// 如果需要强制限制,可以调用 SetMaxCacheSize
}
return stats_.success;
}
// ==================== 访问器 ====================
const std::vector<Error>& SymbolTableBuilder::GetErrors() const
{
return error_reporter_.GetErrors();
}
bool SymbolTableBuilder::HasErrors() const
{
return error_reporter_.HasErrors();
}
size_t SymbolTableBuilder::ErrorCount() const
{
return error_reporter_.ErrorCount();
}
void SymbolTableBuilder::ClearErrors()
{
error_reporter_.Clear();
}
// ==================== 增量配置 ====================
void SymbolTableBuilder::EnableIncremental(bool enable)
{
incremental_enabled_ = enable;
if (enable && !incremental_engine_)
{
incremental_engine_ = std::make_unique<IncrementalEngine>();
}
}
void SymbolTableBuilder::SetMaxCacheSize(size_t max_size)
{
if (incremental_engine_)
{
incremental_engine_->SetMaxCacheSize(max_size);
}
}
void SymbolTableBuilder::ClearCache()
{
if (incremental_engine_)
{
incremental_engine_->Clear();
}
}
size_t SymbolTableBuilder::GetCacheSize() const
{
if (incremental_engine_)
{
return incremental_engine_->GetCacheSize();
}
return 0;
}
}
@@ -0,0 +1,105 @@
#pragma once
#include <vector>
#include <memory>
#include "../../ast/types.hpp"
#include "../../ast/deserializer.hpp"
#include "../core/registry.hpp"
#include "../core/error.hpp"
namespace lsp::language::symbol
{
// 前向声明
class IncrementalEngine;
// ==================== 构建统计信息 ====================
struct BuildStatistics
{
size_t total_symbols = 0; // 总符号数
size_t reused_symbols = 0; // 复用的符号数
size_t new_symbols = 0; // 新创建的符号数
double reuse_rate = 0.0; // 复用率
bool is_incremental = false; // 是否为增量构建
bool success = false; // 构建是否成功
};
// ==================== 符号表构建器 ====================
/**
* 符号表构建器 - 简化为调度器
*
* 职责:
* - 提供构建入口(完整/增量)
* - 管理核心组件(Registry、ErrorReporter
* - 管理增量引擎(可选)
* - 收集和提供统计信息
*
* 不负责:
* - 具体的符号收集逻辑(委托给 Collector)
* - 增量细节(委托给 IncrementalEngine
* - 语义分析(属于后续阶段)
*/
class SymbolTableBuilder
{
public:
SymbolTableBuilder();
~SymbolTableBuilder();
// 禁止拷贝
SymbolTableBuilder(const SymbolTableBuilder&) = delete;
SymbolTableBuilder& operator=(const SymbolTableBuilder&) = delete;
bool Build(const std::vector<ast::ASTNode>& nodes);
bool BuildIncremental(const ast::IncrementalParseResult& parse_result);
SymbolRegistry& GetRegistry() { return registry_; }
const SymbolRegistry& GetRegistry() const { return registry_; }
const std::vector<Error>& GetErrors() const;
bool HasErrors() const;
size_t ErrorCount() const;
void ClearErrors();
BuildStatistics GetStatistics() const { return stats_; }
void EnableIncremental(bool enable);
void SetMaxCacheSize(size_t max_size);
void ClearCache();
size_t GetCacheSize() const;
bool IsIncrementalEnabled() const { return incremental_enabled_; }
private:
// 核心组件
SymbolRegistry registry_;
ErrorReporter error_reporter_;
// 增量支持(可选)
std::unique_ptr<IncrementalEngine> incremental_engine_;
bool incremental_enabled_;
// 统计信息
BuildStatistics stats_;
};
// ==================== 便捷函数 ====================
/**
* 便捷函数:一次性构建符号表
*
* @param nodes AST节点列表
* @param errors 可选的错误输出参数
* @return 构建好的符号注册表(移动语义)
*/
inline SymbolRegistry BuildSymbolTable(const std::vector<ast::ASTNode>& nodes, std::vector<Error>* errors = nullptr)
{
SymbolTableBuilder builder;
builder.Build(nodes);
if (errors)
*errors = builder.GetErrors();
// 移动 Registry(避免拷贝)
return std::move(builder.GetRegistry());
}
}
@@ -0,0 +1,100 @@
#pragma once
#include <sstream>
#include "../core/registry.hpp"
#include "../core/error.hpp"
#include "../factory/scope_manager.hpp"
namespace lsp::language::symbol
{
/**
* 收集上下文 - 封装收集过程中的共享状态
*
* 职责:
* - 提供对 Registry、ErrorReporter、ScopeManager 的统一访问
* - 维护当前上下文(当前 Unit、当前 Class)
* - 提供便捷的错误报告接口
*/
struct CollectorContext
{
SymbolRegistry& registry;
ErrorReporter& error_reporter;
ScopeManager scope_manager;
// 当前上下文
Unit* current_unit = nullptr;
Class* current_class = nullptr;
CollectorContext(SymbolRegistry& reg, ErrorReporter& reporter) :
registry(reg), error_reporter(reporter), scope_manager(reg.GlobalScope())
{
}
// 便捷访问
Table* CurrentScope() { return scope_manager.Current(); }
Table* GlobalScope() { return registry.GlobalScope(); }
// ==================== 改进的错误报告 ====================
void ReportError(ErrorKind kind, const std::string& msg, const ast::Location& loc)
{
error_reporter.Report(kind, msg, loc);
}
void ReportDuplicateDefinition(const std::string& name, const ast::Location& loc)
{
// 查找已存在的符号位置
auto existing = CurrentScope()->LookupLocal(name);
if (existing && existing.symbol)
{
std::ostringstream msg;
msg << "Symbol '" << name << "' already defined at "
<< existing.symbol->location.start_line << ":"
<< existing.symbol->location.start_column;
error_reporter.Report(ErrorKind::kDuplicateDefinition, msg.str(), loc);
}
else
{
error_reporter.ReportDuplicateDefinition(name, loc);
}
}
void ReportSignatureConflict(const std::string& name, const ast::Location& loc)
{
// 查找冲突的函数重载
auto overloads = CurrentScope()->LookupOverloads(name);
if (!overloads.empty())
{
std::ostringstream msg;
msg << "Function signature conflict: '" << name
<< "' (conflicts with overload at "
<< overloads[0]->location.start_line << ":"
<< overloads[0]->location.start_column << ")";
error_reporter.Report(ErrorKind::kSignatureConflict, msg.str(), loc);
}
else
{
error_reporter.Report(ErrorKind::kSignatureConflict,
"Function signature conflict: " + name,
loc);
}
}
void ReportUnitConflict(const std::string& name, const ast::Location& loc)
{
auto existing_unit = registry.FindUnit(name);
if (existing_unit)
{
std::ostringstream msg;
msg << "Unit '" << name << "' already defined at "
<< existing_unit->location.start_line << ":"
<< existing_unit->location.start_column;
error_reporter.Report(ErrorKind::kDuplicateDefinition, msg.str(), loc);
}
else
{
error_reporter.ReportDuplicateDefinition(name, loc);
}
}
};
}
@@ -0,0 +1,87 @@
#include "./incremental_collector.hpp"
#include "../incremental/incremental_engine.hpp"
namespace lsp::language::symbol
{
IncrementalCollector::IncrementalCollector(CollectorContext& context, IncrementalEngine& engine) :
SymbolCollector(context), engine_(engine)
{
}
bool IncrementalCollector::CollectIncremental(const ast::IncrementalParseResult& parse_result)
{
// 重置统计
reused_count_ = 0;
new_count_ = 0;
// 构建变化节点索引
std::unordered_set<size_t> changed_set(
parse_result.changed_indices.begin(),
parse_result.changed_indices.end());
// 处理所有节点
for (size_t i = 0; i < parse_result.result.nodes.size(); ++i)
{
const auto& node = parse_result.result.nodes[i];
bool is_changed = changed_set.count(i) > 0;
if (!ProcessNode(node, is_changed))
return false;
}
return !ctx_.error_reporter.HasErrors();
}
bool IncrementalCollector::ProcessNode(const ast::ASTNode& node, bool is_changed)
{
if (is_changed)
{
// 节点已变化,必须重新收集
new_count_++;
bool success = Visit(node);
if (success)
{
// 收集成功后,缓存新符号
CacheCurrentSymbol(node);
}
return success;
}
else
{
// 节点未变化,尝试复用缓存
if (TryReuseFromCache(node))
{
reused_count_++;
return true;
}
else
{
// 缓存未命中,重新收集
new_count_++;
bool success = Visit(node);
if (success)
{
CacheCurrentSymbol(node);
}
return success;
}
}
}
bool IncrementalCollector::TryReuseFromCache(const ast::ASTNode& node)
{
// 委托给增量引擎,传入 Registry 用于 Unit 复用
return engine_.TryReuseSymbol(node, ctx_.CurrentScope(), &ctx_.registry);
}
void IncrementalCollector::CacheCurrentSymbol(const ast::ASTNode& node)
{
// 委托给增量引擎
engine_.CacheSymbol(node, ctx_.CurrentScope());
}
}
@@ -0,0 +1,47 @@
#pragma once
#include "./symbol_collector.hpp"
#include "../../ast/deserializer.hpp"
namespace lsp::language::symbol
{
// 前向声明
class IncrementalEngine;
/**
* 增量符号收集器
*
* 职责:
* - 继承基础收集器的所有能力
* - 根据节点是否变化决定复用或重新收集
* - 委托 IncrementalEngine 进行缓存操作
* - 收集统计信息
*/
class IncrementalCollector : public SymbolCollector
{
public:
IncrementalCollector(CollectorContext& context, IncrementalEngine& engine);
// 增量收集入口
bool CollectIncremental(const ast::IncrementalParseResult& parse_result);
// 统计信息
size_t GetReusedCount() const { return reused_count_; }
size_t GetNewCount() const { return new_count_; }
private:
// 处理单个节点(判断是复用还是重新收集)
bool ProcessNode(const ast::ASTNode& node, bool is_changed);
// 尝试从缓存复用符号
bool TryReuseFromCache(const ast::ASTNode& node);
// 缓存当前收集的符号
void CacheCurrentSymbol(const ast::ASTNode& node);
private:
IncrementalEngine& engine_;
size_t reused_count_ = 0;
size_t new_count_ = 0;
};
}
@@ -0,0 +1,518 @@
#include "./symbol_collector.hpp"
#include "../utils/type.hpp"
#include "../factory/factory.hpp"
namespace lsp::language::symbol
{
SymbolCollector::SymbolCollector(CollectorContext& context) :
ctx_(context)
{
}
bool SymbolCollector::Collect(const std::vector<ast::ASTNode>& nodes)
{
for (const auto& node : nodes)
{
if (!Visit(node))
return false;
}
return !ctx_.error_reporter.HasErrors();
}
// ==================== AST 访问 ====================
bool SymbolCollector::Visit(const ast::ASTNode& node)
{
if (std::holds_alternative<std::monostate>(node))
return true;
if (auto* unit = std::get_if<ast::UnitDefinition>(&node))
return CollectUnit(*unit);
if (auto* global = std::get_if<ast::GlobalDeclaration>(&node))
return CollectGlobal(*global);
if (auto* static_decl = std::get_if<ast::StaticDeclaration>(&node))
return CollectStatic(*static_decl);
if (auto* var = std::get_if<ast::VarDeclaration>(&node))
return CollectVariable(*var);
if (auto* constant = std::get_if<ast::ConstDeclaration>(&node))
return CollectConstant(*constant);
if (auto* stmt = std::get_if<ast::AssignmentStatement>(&node))
return CollectAssignment(*stmt);
if (auto* func_def = std::get_if<ast::FunctionDefinition>(&node))
return CollectFunctionDef(*func_def);
if (auto* cls = std::get_if<ast::ClassDefinition>(&node))
return CollectClass(*cls);
if (auto* uses = std::get_if<ast::UsesClause>(&node))
return CollectUsesClause(*uses);
// 跳过表达式和块
if (std::holds_alternative<ast::Expression>(node) ||
std::holds_alternative<ast::Block>(node))
return true;
return true;
}
// ==================== 收集方法 ====================
bool SymbolCollector::CollectUnit(const ast::UnitDefinition& unit)
{
auto unit_symbol = factory::CreateUnit(unit.name, unit.location);
if (!TryInsertUnit(unit_symbol))
return false;
ctx_.current_unit = unit_symbol.get();
// 创建 interface 和 implementation 作用域
unit_symbol->interface_symbols =
std::make_unique<Table>(ScopeKind::kInterface, ctx_.GlobalScope());
unit_symbol->implementation_symbols =
std::make_unique<Table>(ScopeKind::kImplementation, ctx_.GlobalScope());
// 收集 uses 子句
if (unit.uses)
CollectUsesClause(*unit.uses);
// 收集各部分的声明
CollectInScope(unit_symbol->interface_symbols.get(), unit.interface_statements);
CollectInScope(unit_symbol->implementation_symbols.get(), unit.implementation_statements);
CollectInScope(unit_symbol->implementation_symbols.get(), unit.initialization_statements);
CollectInScope(unit_symbol->implementation_symbols.get(), unit.finalization_statements);
ctx_.current_unit = nullptr;
return true;
}
bool SymbolCollector::CollectGlobal(const ast::GlobalDeclaration& global)
{
TypeInfo type = global.type_name ?
TypeFactory::FromAnnotation(*global.type_name) :
TypeInfo();
auto var_symbol = factory::CreateVariable(
global.name, Kind::kGlobalVariable, global.location, type);
if (global.value)
var_symbol->initialization_expr = global.value->text;
return TryInsert(var_symbol);
}
bool SymbolCollector::CollectStatic(const ast::StaticDeclaration& decl)
{
TypeInfo type = decl.type_name ?
TypeFactory::FromAnnotation(*decl.type_name) :
TypeInfo();
auto var_symbol = factory::CreateVariable(
decl.name, Kind::kStaticVariable, decl.location, type);
var_symbol->attributes.is_static = true;
if (decl.value)
var_symbol->initialization_expr = decl.value->text;
return TryInsert(var_symbol);
}
bool SymbolCollector::CollectVariable(const ast::VarDeclaration& var)
{
TypeInfo type = var.type_name ?
TypeFactory::FromAnnotation(*var.type_name) :
TypeInfo();
auto var_symbol = factory::CreateVariable(
var.name, Kind::kVariable, var.location, type);
if (var.value)
var_symbol->initialization_expr = var.value->text;
return TryInsert(var_symbol);
}
bool SymbolCollector::CollectConstant(const ast::ConstDeclaration& constant)
{
TypeInfo type = constant.type_name ?
TypeFactory::FromAnnotation(*constant.type_name) :
TypeInfo();
auto const_symbol = factory::CreateConstant(
constant.name, constant.location, type, constant.value.text);
return TryInsert(const_symbol);
}
bool SymbolCollector::CollectAssignment(const ast::AssignmentStatement& stmt)
{
TypeInfo type;
auto var_symbol = factory::CreateVariable(
stmt.name, Kind::kVariable, stmt.location, type);
var_symbol->initialization_expr = stmt.value.text;
return TryInsert(var_symbol);
}
bool SymbolCollector::CollectFunctionDef(const ast::FunctionDefinition& func)
{
Signature sig = CreateSignature(func.signature);
auto func_symbol = factory::CreateFunction(
func.name, func.location, sig);
if (!TryInsertFunction(func_symbol, func.location))
return false;
// 收集函数体
if (!func.body.statements.empty())
CollectFunctionBody(func_symbol.get(), func.body);
return true;
}
bool SymbolCollector::CollectClass(const ast::ClassDefinition& class_def)
{
auto class_symbol = factory::CreateClass(
class_def.name, class_def.location);
// 存储父类名称(字符串形式,不解析引用)
class_symbol->parent_names = class_def.parents;
if (!TryInsert(class_symbol))
return false;
// 创建成员作用域
class_symbol->members = std::make_unique<Table>(
ScopeKind::kClass, ctx_.CurrentScope());
ctx_.current_class = class_symbol.get();
// 进入类作用域,收集成员
auto guard = ctx_.scope_manager.EnterScope(class_symbol->members.get());
for (const auto& member : class_def.members)
{
CollectClassMember(member, class_symbol.get());
}
ctx_.current_class = nullptr;
return true;
}
bool SymbolCollector::CollectUsesClause(const ast::UsesClause& uses)
{
if (ctx_.current_unit)
ctx_.current_unit->uses = uses.units;
return true;
}
// ==================== 类成员收集 ====================
bool SymbolCollector::CollectClassMember(const ast::ClassMember& member, Class* owner)
{
if (std::holds_alternative<std::monostate>(member.content))
return true;
Access access = member.access;
if (auto* var = std::get_if<ast::VarDeclaration>(&member.content))
return CollectMemberVariable(*var, access);
if (auto* static_decl = std::get_if<ast::StaticDeclaration>(&member.content))
return CollectMemberStatic(*static_decl, access);
if (auto* method = std::get_if<ast::Method>(&member.content))
return CollectMemberMethod(*method, access, owner);
if (auto* property = std::get_if<ast::Property>(&member.content))
return CollectMemberProperty(*property, access);
if (auto* ctor = std::get_if<ast::ConstructorDeclaration>(&member.content))
return CollectMemberConstructor(*ctor, access, owner);
if (auto* dtor = std::get_if<ast::DestructorDeclaration>(&member.content))
return CollectMemberDestructor(*dtor, access, owner);
return true;
}
bool SymbolCollector::CollectMemberVariable(const ast::VarDeclaration& var, Access access)
{
TypeInfo type = var.type_name ?
TypeFactory::FromAnnotation(*var.type_name) :
TypeInfo();
auto var_symbol = factory::CreateVariable(
var.name, Kind::kVariable, var.location, type);
var_symbol->attributes.access = access;
if (var.value)
var_symbol->initialization_expr = var.value->text;
return TryInsert(var_symbol);
}
bool SymbolCollector::CollectMemberStatic(const ast::StaticDeclaration& decl, Access access)
{
TypeInfo type = decl.type_name ?
TypeFactory::FromAnnotation(*decl.type_name) :
TypeInfo();
auto var_symbol = factory::CreateVariable(
decl.name, Kind::kStaticVariable, decl.location, type);
var_symbol->attributes.access = access;
var_symbol->attributes.is_static = true;
if (decl.value)
var_symbol->initialization_expr = decl.value->text;
return TryInsert(var_symbol);
}
bool SymbolCollector::CollectMemberMethod(const ast::Method& method,
Access access,
Class* owner)
{
Signature sig = CreateSignature(method.signature);
auto method_symbol = factory::CreateMethod(
method.name, method.location, sig, owner);
method_symbol->attributes.access = access;
method_symbol->attributes.is_class_method = method.is_class_method;
// 设置 virtual/override 属性
switch (method.modifier)
{
case ast::Modifier::kVirtual:
method_symbol->attributes.is_virtual = true;
break;
case ast::Modifier::kOverride:
method_symbol->attributes.is_override = true;
break;
case ast::Modifier::kOverload:
method_symbol->attributes.is_overload = true;
break;
case ast::Modifier::kNone:
default:
break;
}
if (!TryInsertFunction(method_symbol, method.location))
return false;
// 收集方法体
if (method.body)
CollectFunctionBody(method_symbol.get(), *method.body);
return true;
}
bool SymbolCollector::CollectMemberProperty(const ast::Property& property, Access access)
{
TypeInfo type = property.type_name ?
TypeFactory::FromAnnotation(*property.type_name) :
TypeInfo();
auto property_symbol = factory::CreateProperty(
property.name, property.location, type);
property_symbol->attributes.access = access;
property_symbol->getter = property.getter;
property_symbol->setter = property.setter;
return TryInsert(property_symbol);
}
bool SymbolCollector::CollectMemberConstructor(const ast::ConstructorDeclaration& ctor,
Access access,
Class* owner)
{
Signature sig = CreateSignature(ctor.signature);
auto ctor_symbol = factory::CreateConstructor(
"Create", ctor.location, sig, owner);
ctor_symbol->attributes.access = access;
if (!TryInsert(ctor_symbol))
return false;
// 收集构造函数体
if (ctor.body)
CollectConstructorBody(ctor_symbol.get(), *ctor.body);
return true;
}
bool SymbolCollector::CollectMemberDestructor(const ast::DestructorDeclaration& dtor,
Access access,
Class* owner)
{
auto dtor_symbol = factory::CreateDestructor(
"Destroy", dtor.location, owner);
dtor_symbol->attributes.access = access;
if (!TryInsert(dtor_symbol))
return false;
// 收集析构函数体
if (dtor.body)
CollectDestructorBody(dtor_symbol.get(), *dtor.body);
return true;
}
// ==================== 函数体收集 ====================
void SymbolCollector::CollectFunctionBody(Function* func, const ast::Block& body)
{
// 创建函数作用域
func->body_scope = std::make_unique<Table>(
ScopeKind::kFunction, ctx_.CurrentScope());
// 进入函数作用域
auto guard = ctx_.scope_manager.EnterScope(func->body_scope.get());
// 收集参数符号
CollectFunctionParams(func);
// 收集函数体中的局部声明
CollectStatements(body.statements);
}
void SymbolCollector::CollectFunctionParams(Function* func)
{
for (const auto& param : func->signature.parameters)
{
auto param_symbol = factory::CreateVariable(
param.name, Kind::kParameter, func->location, param.type);
param_symbol->attributes.is_var_param = param.is_var;
param_symbol->attributes.is_out_param = param.is_out;
func->body_scope->Insert(param_symbol);
}
}
void SymbolCollector::CollectConstructorBody(Constructor* ctor, const ast::Block& body)
{
ctor->body_scope = std::make_unique<Table>(
ScopeKind::kFunction, ctx_.CurrentScope());
auto guard = ctx_.scope_manager.EnterScope(ctor->body_scope.get());
// 收集参数
for (const auto& param : ctor->signature.parameters)
{
auto param_symbol = factory::CreateVariable(
param.name, Kind::kParameter, ctor->location, param.type);
param_symbol->attributes.is_var_param = param.is_var;
param_symbol->attributes.is_out_param = param.is_out;
ctor->body_scope->Insert(param_symbol);
}
CollectStatements(body.statements);
}
void SymbolCollector::CollectDestructorBody(Destructor* dtor, const ast::Block& body)
{
dtor->body_scope = std::make_unique<Table>(
ScopeKind::kFunction, ctx_.CurrentScope());
auto guard = ctx_.scope_manager.EnterScope(dtor->body_scope.get());
CollectStatements(body.statements);
}
// ==================== 辅助方法 ====================
void SymbolCollector::CollectInScope(Table* scope,
const std::vector<ast::ASTNode>& statements)
{
auto guard = ctx_.scope_manager.EnterScope(scope);
CollectStatements(statements);
}
void SymbolCollector::CollectStatements(const std::vector<ast::ASTNode>& statements)
{
for (const auto& stmt : statements)
Visit(stmt);
}
// ==================== 插入方法 ====================
bool SymbolCollector::TryInsert(SymbolPtr symbol)
{
if (!ctx_.CurrentScope()->Insert(symbol))
{
ctx_.ReportDuplicateDefinition(symbol->name, symbol->location);
return false;
}
return true;
}
bool SymbolCollector::TryInsertFunction(FunctionPtr func, const ast::Location& loc)
{
if (!ctx_.CurrentScope()->InsertFunction(func))
{
ctx_.ReportSignatureConflict(func->name, loc);
return false;
}
return true;
}
bool SymbolCollector::TryInsertUnit(UnitPtr unit)
{
if (!ctx_.registry.AddUnit(unit))
{
ctx_.ReportUnitConflict(unit->name, unit->location);
return false;
}
return true;
}
// ==================== 创建签名 ====================
Signature SymbolCollector::CreateSignature(const ast::Signature& ast_sig)
{
Signature sig;
for (const auto& ast_param : ast_sig.parameters)
{
sig.parameters.push_back(CreateParameter(ast_param));
}
if (ast_sig.return_type)
sig.return_type = TypeFactory::FromAnnotation(*ast_sig.return_type);
return sig;
}
Signature::Param SymbolCollector::CreateParameter(const ast::Parameter& ast_param)
{
Signature::Param param;
param.name = ast_param.name;
param.type = ast_param.type_name ?
TypeFactory::FromAnnotation(*ast_param.type_name) :
TypeInfo();
param.is_var = ast_param.is_var;
param.is_out = ast_param.is_out;
param.default_value = ast_param.default_value;
return param;
}
}
@@ -0,0 +1,86 @@
#pragma once
#include <vector>
#include "../../ast/types.hpp"
#include "./context.hpp"
namespace lsp::language::symbol
{
/**
* 符号收集器 - 负责从 AST 收集符号
*
* 职责:
* - 遍历 AST 节点
* - 创建符号对象
* - 插入作用域
* - 管理作用域切换
*
* 不负责:
* - 增量构建逻辑
* - 缓存管理
* - 依赖追踪
* - 类型引用解析(保持字符串形式)
*/
class SymbolCollector
{
public:
explicit SymbolCollector(CollectorContext& context);
virtual ~SymbolCollector() = default;
// 主入口 - 收集所有节点
bool Collect(const std::vector<ast::ASTNode>& nodes);
protected:
// ==================== AST 访问 ====================
virtual bool Visit(const ast::ASTNode& node);
// ==================== 顶层声明 ====================
bool CollectUnit(const ast::UnitDefinition& unit);
bool CollectGlobal(const ast::GlobalDeclaration& global);
bool CollectStatic(const ast::StaticDeclaration& decl);
bool CollectVariable(const ast::VarDeclaration& var);
bool CollectConstant(const ast::ConstDeclaration& constant);
bool CollectAssignment(const ast::AssignmentStatement& stmt);
bool CollectFunctionDef(const ast::FunctionDefinition& func);
bool CollectClass(const ast::ClassDefinition& class_def);
bool CollectUsesClause(const ast::UsesClause& uses);
// ==================== 类成员收集 ====================
bool CollectClassMember(const ast::ClassMember& member, Class* owner);
bool CollectMemberVariable(const ast::VarDeclaration& var, Access access);
bool CollectMemberStatic(const ast::StaticDeclaration& decl, Access access);
bool CollectMemberMethod(const ast::Method& method, Access access, Class* owner);
bool CollectMemberProperty(const ast::Property& property, Access access);
bool CollectMemberConstructor(const ast::ConstructorDeclaration& ctor, Access access, Class* owner);
bool CollectMemberDestructor(const ast::DestructorDeclaration& dtor, Access access, Class* owner);
// ==================== 函数体收集 ====================
void CollectFunctionBody(Function* func, const ast::Block& body);
void CollectFunctionParams(Function* func);
void CollectConstructorBody(Constructor* ctor, const ast::Block& body);
void CollectDestructorBody(Destructor* dtor, const ast::Block& body);
// ==================== 辅助方法 ====================
void CollectInScope(Table* scope, const std::vector<ast::ASTNode>& statements);
void CollectStatements(const std::vector<ast::ASTNode>& statements);
// ==================== 插入方法 ====================
bool TryInsert(SymbolPtr symbol);
bool TryInsertFunction(FunctionPtr func, const ast::Location& loc);
bool TryInsertUnit(UnitPtr unit);
// ==================== 创建签名 ====================
Signature CreateSignature(const ast::Signature& ast_sig);
Signature::Param CreateParameter(const ast::Parameter& ast_param);
protected:
CollectorContext& ctx_;
};
}
@@ -0,0 +1,108 @@
#include <sstream>
#include <unordered_map>
#include "./error.hpp"
namespace lsp::language::symbol
{
// ==================== 错误类型名称映射 ====================
namespace
{
const char* GetErrorKindName(ErrorKind kind)
{
static const std::unordered_map<ErrorKind, const char*> names = {
{ ErrorKind::kDuplicateDefinition, "Duplicate definition" },
{ ErrorKind::kSignatureConflict, "Signature conflict" },
{ ErrorKind::kUndefinedType, "Undefined type" },
{ ErrorKind::kInvalidAccess, "Invalid access" },
{ ErrorKind::kCircularDependency, "Circular dependency" },
{ ErrorKind::kInvalidOverride, "Invalid override" },
{ ErrorKind::kInvalidTypeReference, "Invalid type reference" },
{ ErrorKind::kMemberNotFound, "Member not found" },
{ ErrorKind::kInvalidModifier, "Invalid modifier" },
{ ErrorKind::kInvalidParent, "Invalid parent" },
};
auto it = names.find(kind);
return it != names.end() ? it->second : "Unknown error";
}
}
// ==================== Error 实现 ====================
Error::Error(ErrorKind k, const std::string& msg, const ast::Location& loc) :
kind(k), message(msg), location(loc)
{
}
std::string Error::ToString() const
{
std::ostringstream oss;
oss << "[" << location.start_line << ":" << location.start_column << "] ";
oss << GetErrorKindName(kind);
oss << ": " << message;
return oss.str();
}
Error Error::DuplicateDefinition(const std::string& name, const ast::Location& loc)
{
return Error(ErrorKind::kDuplicateDefinition, "Duplicate definition: " + name, loc);
}
Error Error::UndefinedType(const std::string& type, const ast::Location& loc)
{
return Error(ErrorKind::kUndefinedType, "Undefined type: " + type, loc);
}
Error Error::CircularDependency(const std::string& msg, const ast::Location& loc)
{
return Error(ErrorKind::kCircularDependency, msg, loc);
}
// ==================== ErrorReporter 实现 ====================
void ErrorReporter::Report(ErrorKind kind, const std::string& msg, const ast::Location& loc)
{
errors_.emplace_back(kind, msg, loc);
}
void ErrorReporter::Report(const Error& error)
{
errors_.push_back(error);
}
const std::vector<Error>& ErrorReporter::GetErrors() const
{
return errors_;
}
bool ErrorReporter::HasErrors() const
{
return !errors_.empty();
}
size_t ErrorReporter::ErrorCount() const
{
return errors_.size();
}
void ErrorReporter::Clear()
{
errors_.clear();
}
void ErrorReporter::ReportDuplicateDefinition(const std::string& name, const ast::Location& loc)
{
Report(Error::DuplicateDefinition(name, loc));
}
void ErrorReporter::ReportUndefinedType(const std::string& type, const ast::Location& loc)
{
Report(Error::UndefinedType(type, loc));
}
void ErrorReporter::ReportCircularDependency(const std::string& msg, const ast::Location& loc)
{
Report(Error::CircularDependency(msg, loc));
}
}
@@ -0,0 +1,56 @@
#pragma once
#include <string>
#include "../../ast/types.hpp"
namespace lsp::language::symbol
{
enum class ErrorKind
{
kDuplicateDefinition,
kSignatureConflict,
kUndefinedType,
kInvalidAccess,
kCircularDependency,
kInvalidOverride,
kInvalidTypeReference,
kMemberNotFound,
kInvalidModifier,
kInvalidParent,
};
struct Error
{
ErrorKind kind;
std::string message;
ast::Location location;
Error(ErrorKind k, const std::string& msg, const ast::Location& loc);
std::string ToString() const;
static Error DuplicateDefinition(const std::string& name, const ast::Location& loc);
static Error UndefinedType(const std::string& type, const ast::Location& loc);
static Error CircularDependency(const std::string& msg, const ast::Location& loc);
};
class ErrorReporter
{
public:
ErrorReporter() = default;
void Report(ErrorKind kind, const std::string& msg, const ast::Location& loc);
void Report(const Error& error);
const std::vector<Error>& GetErrors() const;
bool HasErrors() const;
size_t ErrorCount() const;
void Clear();
void ReportDuplicateDefinition(const std::string& name, const ast::Location& loc);
void ReportUndefinedType(const std::string& type, const ast::Location& loc);
void ReportCircularDependency(const std::string& msg, const ast::Location& loc);
private:
std::vector<Error> errors_;
};
}
@@ -0,0 +1,100 @@
#include "./registry.hpp"
namespace lsp::language::symbol
{
SymbolRegistry::SymbolRegistry() :
global_scope_(ScopeKind::kGlobal, nullptr)
{
}
// 移动构造函数
SymbolRegistry::SymbolRegistry(SymbolRegistry&& other) noexcept :
global_scope_(std::move(other.global_scope_)),
units_(std::move(other.units_))
{
// 修复 global_scope_ 中所有符号的 scope 指针
for (auto& [name, symbol] : global_scope_.Symbols())
{
if (symbol && symbol->scope == &other.global_scope_)
{
symbol->scope = &global_scope_;
}
}
// 修复 units_ 中所有符号的 scope 指针
for (auto& [name, unit] : units_)
{
if (unit && unit->scope == &other.global_scope_)
{
unit->scope = &global_scope_;
}
}
}
// 移动赋值运算符
SymbolRegistry& SymbolRegistry::operator=(SymbolRegistry&& other) noexcept
{
if (this != &other)
{
global_scope_ = std::move(other.global_scope_);
units_ = std::move(other.units_);
// 修复 global_scope_ 中所有符号的 scope 指针
for (auto& [name, symbol] : global_scope_.Symbols())
{
if (symbol && symbol->scope == &other.global_scope_)
{
symbol->scope = &global_scope_;
}
}
// 修复 units_ 中所有符号的 scope 指针
for (auto& [name, unit] : units_)
{
if (unit && unit->scope == &other.global_scope_)
{
unit->scope = &global_scope_;
}
}
}
return *this;
}
Table* SymbolRegistry::GlobalScope()
{
return &global_scope_;
}
const Table* SymbolRegistry::GlobalScope() const
{
return &global_scope_;
}
bool SymbolRegistry::AddUnit(UnitPtr unit)
{
if (!unit)
return false;
if (units_.count(unit->name) > 0)
return false;
if (!global_scope_.Insert(unit))
return false;
units_[unit->name] = unit;
return true;
}
UnitPtr SymbolRegistry::FindUnit(const std::string& name) const
{
auto it = units_.find(name);
if (it != units_.end())
return it->second;
return nullptr;
}
const std::unordered_map<std::string, UnitPtr>& SymbolRegistry::Units() const
{
return units_;
}
}
@@ -0,0 +1,37 @@
#pragma once
#include <unordered_map>
#include "./symbol.hpp"
#include "./table.hpp"
namespace lsp::language::symbol
{
class SymbolRegistry
{
public:
SymbolRegistry();
~SymbolRegistry() = default;
SymbolRegistry(const SymbolRegistry&) = delete;
SymbolRegistry& operator=(const SymbolRegistry&) = delete;
// 自定义移动构造和移动赋值
SymbolRegistry(SymbolRegistry&& other) noexcept;
SymbolRegistry& operator=(SymbolRegistry&& other) noexcept;
// ==================== 访问全局作用域 ====================
Table* GlobalScope();
const Table* GlobalScope() const;
// ==================== Unit 管理 ====================
bool AddUnit(UnitPtr unit);
UnitPtr FindUnit(const std::string& name) const;
const std::unordered_map<std::string, UnitPtr>& Units() const;
private:
Table global_scope_;
std::unordered_map<std::string, UnitPtr> units_;
};
}
@@ -0,0 +1,78 @@
#include "./symbol.hpp"
#include "./table.hpp"
namespace lsp::language::symbol
{
// ==================== Function 实现 ====================
Function::Function(const std::string& name, const ast::Location& loc, const Signature& sig) :
Symbol(name, Kind::kFunction, loc), signature(sig), is_overload(false), body_scope(nullptr)
{
}
Function::~Function() = default;
Function::Function(Function&&) noexcept = default;
Function& Function::operator=(Function&&) noexcept = default;
// ==================== Method 实现 ====================
Method::Method(const std::string& name, const ast::Location& loc, const Signature& sig) :
Function(name, loc, sig), owner_class(nullptr)
{
kind = Kind::kMethod;
}
// ==================== Constructor 实现 ====================
Constructor::Constructor(const std::string& name, const ast::Location& loc, const Signature& sig) :
Symbol(name, Kind::kConstructor, loc), signature(sig), owner_class(nullptr), body_scope(nullptr)
{
}
Constructor::~Constructor() = default;
Constructor::Constructor(Constructor&&) noexcept = default;
Constructor& Constructor::operator=(Constructor&&) noexcept = default;
// ==================== Destructor 实现 ====================
Destructor::Destructor(const std::string& name, const ast::Location& loc) :
Symbol(name, Kind::kDestructor, loc), owner_class(nullptr), body_scope(nullptr)
{
}
Destructor::~Destructor() = default;
Destructor::Destructor(Destructor&&) noexcept = default;
Destructor& Destructor::operator=(Destructor&&) noexcept = default;
// ==================== Class 实现 ====================
Class::Class(const std::string& name, const ast::Location& loc) :
Symbol(name, Kind::kClass, loc), members(nullptr)
{
}
Class::~Class() = default;
Class::Class(Class&&) noexcept = default;
Class& Class::operator=(Class&&) noexcept = default;
// ==================== Unit 实现 ====================
Unit::Unit(const std::string& name, const ast::Location& loc) :
Symbol(name, Kind::kUnit, loc), interface_symbols(nullptr), implementation_symbols(nullptr)
{
}
Unit::~Unit() = default;
Unit::Unit(Unit&&) noexcept = default;
Unit& Unit::operator=(Unit&&) noexcept = default;
}
@@ -0,0 +1,270 @@
#pragma once
#include <string>
#include <vector>
#include <optional>
#include <memory>
#include "../../ast/types.hpp"
namespace lsp::language::symbol
{
// 前向声明
class Table;
// ==================== 基本枚举 ====================
enum class Kind
{
kVariable,
kStaticVariable,
kGlobalVariable,
kConstant,
kParameter,
kFunction,
kClass,
kMethod,
kConstructor,
kDestructor,
kProperty,
kUnit,
};
enum class ScopeKind
{
kGlobal,
kUnit,
kInterface,
kImplementation,
kFunction,
kClass,
kBlock,
};
using Access = ast::Access;
// ==================== 符号属性 ====================
struct Attributes
{
bool is_const = false;
bool is_static = false;
bool is_var_param = false;
bool is_out_param = false;
Access access = Access::kPublic;
bool is_virtual = false;
bool is_override = false;
bool is_overload = false;
bool is_class_method = false;
};
// ==================== 类型信息(纯数据) ====================
class TypeInfo
{
public:
TypeInfo() = default;
explicit TypeInfo(const std::string& annotation) :
annotation_(annotation) {}
bool HasAnnotation() const { return !annotation_.empty(); }
const std::string& Annotation() const { return annotation_; }
// bool IsArray() const;
// bool IsPrimitive() const;
private:
std::string annotation_; // 类型注解(原始字符串)
};
// ==================== 函数签名(纯数据) ====================
class Signature
{
public:
size_t ParamCount() const { return parameters.size(); }
bool HasReturnType() const { return return_type.has_value(); }
public:
struct Param
{
std::string name;
TypeInfo type;
bool is_var = false;
bool is_out = false;
std::optional<std::string> default_value;
};
std::vector<Param> parameters;
std::optional<TypeInfo> return_type;
};
// ==================== 符号基类 ====================
class Symbol
{
public:
Symbol(const std::string& name, Kind kind, const ast::Location& loc) :
name(name), kind(kind), location(loc), scope(nullptr)
{
}
virtual ~Symbol() = default;
Symbol(const Symbol&) = delete;
Symbol& operator=(const Symbol&) = delete;
Symbol(Symbol&&) noexcept = default;
Symbol& operator=(Symbol&&) noexcept = default;
public:
std::string name;
Kind kind;
ast::Location location;
Table* scope;
Attributes attributes;
};
// ==================== 具体符号类 ====================
class Variable : public Symbol
{
public:
Variable(const std::string& name, Kind kind, const ast::Location& loc, const TypeInfo& type) :
Symbol(name, kind, loc), type(type)
{
}
public:
TypeInfo type;
std::optional<std::string> initialization_expr;
};
class Constant : public Symbol
{
public:
Constant(const std::string& name, const ast::Location& loc, const TypeInfo& type, const std::string& value) :
Symbol(name, Kind::kConstant, loc), type(type), value(value)
{
attributes.is_const = true;
}
public:
TypeInfo type;
std::string value;
};
class Function : public Symbol
{
public:
Function(const std::string& name, const ast::Location& loc, const Signature& sig);
~Function() override;
Function(const Function&) = delete;
Function& operator=(const Function&) = delete;
Function(Function&&) noexcept;
Function& operator=(Function&&) noexcept;
public:
Signature signature;
bool is_overload;
std::unique_ptr<Table> body_scope;
};
class Method : public Function
{
public:
Method(const std::string& name, const ast::Location& loc, const Signature& sig);
public:
class Class* owner_class;
std::optional<ast::Location> implementation_location;
};
class Constructor : public Symbol
{
public:
Signature signature;
class Class* owner_class;
std::unique_ptr<Table> body_scope;
Constructor(const std::string& name, const ast::Location& loc, const Signature& sig);
~Constructor() override;
Constructor(const Constructor&) = delete;
Constructor& operator=(const Constructor&) = delete;
Constructor(Constructor&&) noexcept;
Constructor& operator=(Constructor&&) noexcept;
};
class Destructor : public Symbol
{
public:
class Class* owner_class;
std::unique_ptr<Table> body_scope;
Destructor(const std::string& name, const ast::Location& loc);
~Destructor() override;
Destructor(const Destructor&) = delete;
Destructor& operator=(const Destructor&) = delete;
Destructor(Destructor&&) noexcept;
Destructor& operator=(Destructor&&) noexcept;
};
class Property : public Symbol
{
public:
TypeInfo type;
std::optional<std::string> getter;
std::optional<std::string> setter;
Property(const std::string& name, const ast::Location& loc, const TypeInfo& type) :
Symbol(name, Kind::kProperty, loc), type(type)
{
}
};
class Class : public Symbol
{
public:
std::vector<std::string> parent_names;
std::vector<Class*> parents;
std::unique_ptr<Table> members;
Class(const std::string& name, const ast::Location& loc);
~Class() override;
Class(const Class&) = delete;
Class& operator=(const Class&) = delete;
Class(Class&&) noexcept;
Class& operator=(Class&&) noexcept;
};
class Unit : public Symbol
{
public:
std::vector<std::string> uses;
std::unique_ptr<Table> interface_symbols;
std::unique_ptr<Table> implementation_symbols;
Unit(const std::string& name, const ast::Location& loc);
~Unit() override;
Unit(const Unit&) = delete;
Unit& operator=(const Unit&) = delete;
Unit(Unit&&) noexcept;
Unit& operator=(Unit&&) noexcept;
};
// ==================== 智能指针类型别名 ====================
using SymbolPtr = std::shared_ptr<Symbol>;
using VariablePtr = std::shared_ptr<Variable>;
using ConstantPtr = std::shared_ptr<Constant>;
using FunctionPtr = std::shared_ptr<Function>;
using MethodPtr = std::shared_ptr<Method>;
using ConstructorPtr = std::shared_ptr<Constructor>;
using DestructorPtr = std::shared_ptr<Destructor>;
using PropertyPtr = std::shared_ptr<Property>;
using ClassPtr = std::shared_ptr<Class>;
using UnitPtr = std::shared_ptr<Unit>;
}
@@ -0,0 +1,146 @@
#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;
}
}
@@ -0,0 +1,69 @@
#pragma once
#include <unordered_map>
#include <vector>
#include <memory>
#include "./symbol.hpp"
namespace lsp::language::symbol
{
// ==================== 查找结果 ====================
struct LookupResult
{
Symbol* symbol = nullptr;
Table* scope = nullptr;
bool success = false;
static LookupResult Found(Symbol* sym, Table* scp);
static LookupResult NotFound();
explicit operator bool() const;
};
// ==================== 符号表 / 作用域 ====================
class Table
{
public:
explicit Table(ScopeKind kind, Table* parent = nullptr);
~Table() = default;
Table(const Table&) = delete;
Table& operator=(const Table&) = delete;
Table(Table&&) noexcept = default;
Table& operator=(Table&&) noexcept = default;
// ==================== 访问器 ====================
ScopeKind Kind() const;
Table* Parent() const;
const std::unordered_map<std::string, SymbolPtr>& Symbols() const;
const std::unordered_map<std::string, std::vector<FunctionPtr>>& OverloadedFunctions() const;
// ==================== 作用域管理 ====================
Table* CreateChild(ScopeKind kind);
// ==================== 符号插入(核心方法) ====================
bool Insert(SymbolPtr symbol);
bool InsertFunction(FunctionPtr func);
// ==================== 符号查找 ====================
LookupResult LookupLocal(const std::string& name) const;
LookupResult Lookup(const std::string& name) const;
// 优化:返回 vector 引用或空 vector
std::vector<FunctionPtr> LookupOverloads(const std::string& name) const;
MethodPtr FindMethodInClass(const std::string& class_name, const std::string& method_name) const;
private:
ScopeKind kind_;
Table* parent_;
std::vector<std::unique_ptr<Table>> children_;
std::unordered_map<std::string, SymbolPtr> symbols_;
std::unordered_map<std::string, std::vector<FunctionPtr>> overloaded_functions_;
};
}
@@ -0,0 +1,114 @@
#include "../utils/type.hpp"
#include "./factory.hpp"
namespace lsp::language::symbol
{
// ==================== 创建符号对象 ====================
VariablePtr factory::CreateVariable(
const std::string& name,
Kind kind,
const ast::Location& loc,
const TypeInfo& type)
{
return std::make_shared<Variable>(name, kind, loc, type);
}
ConstantPtr factory::CreateConstant(
const std::string& name,
const ast::Location& loc,
const TypeInfo& type,
const std::string& value)
{
return std::make_shared<Constant>(name, loc, type, value);
}
FunctionPtr factory::CreateFunction(
const std::string& name,
const ast::Location& loc,
const Signature& sig)
{
return std::make_shared<Function>(name, loc, sig);
}
MethodPtr factory::CreateMethod(
const std::string& name,
const ast::Location& loc,
const Signature& sig,
Class* owner)
{
auto method = std::make_shared<Method>(name, loc, sig);
method->owner_class = owner;
return method;
}
ConstructorPtr factory::CreateConstructor(
const std::string& name,
const ast::Location& loc,
const Signature& sig,
Class* owner)
{
auto ctor = std::make_shared<Constructor>(name, loc, sig);
ctor->owner_class = owner;
return ctor;
}
DestructorPtr factory::CreateDestructor(
const std::string& name,
const ast::Location& loc,
Class* owner)
{
auto dtor = std::make_shared<Destructor>(name, loc);
dtor->owner_class = owner;
return dtor;
}
PropertyPtr factory::CreateProperty(
const std::string& name,
const ast::Location& loc,
const TypeInfo& type)
{
return std::make_shared<Property>(name, loc, type);
}
ClassPtr factory::CreateClass(
const std::string& name,
const ast::Location& loc)
{
return std::make_shared<Class>(name, loc);
}
UnitPtr factory::CreateUnit(
const std::string& name,
const ast::Location& loc)
{
return std::make_shared<Unit>(name, loc);
}
// ==================== 便捷方法 ====================
VariablePtr factory::CreateAndInsert(
Table* table,
const std::string& name,
Kind kind,
const ast::Location& loc,
const TypeInfo& type)
{
auto var = CreateVariable(name, kind, loc, type);
if (table && table->Insert(var))
return var;
return nullptr;
}
VariablePtr factory::CreateVariableFromAST(
const std::string& name,
Kind kind,
const ast::Location& loc,
const std::optional<std::string>& type_str)
{
TypeInfo type = type_str ?
TypeFactory::FromAnnotation(*type_str) :
TypeInfo();
return CreateVariable(name, kind, loc, type);
}
}
@@ -0,0 +1,110 @@
#pragma once
#include <optional>
#include "../../ast/types.hpp"
#include "../core/symbol.hpp"
#include "../core/table.hpp"
namespace lsp::language::symbol
{
/**
* 符号工厂 - 创建符号对象
*
* 职责:
* - 提供符号对象的创建接口
* - 封装 std::make_shared 调用
*
* 不负责:
* - AST 到 Symbol 的转换逻辑(属于 Collector
*/
namespace factory
{
// ==================== 创建符号对象 ====================
/**
* 创建变量符号
*/
VariablePtr CreateVariable(
const std::string& name,
Kind kind,
const ast::Location& loc,
const TypeInfo& type);
/**
* 创建常量符号
*/
ConstantPtr CreateConstant(
const std::string& name,
const ast::Location& loc,
const TypeInfo& type,
const std::string& value);
/**
* 创建函数符号
*/
FunctionPtr CreateFunction(
const std::string& name,
const ast::Location& loc,
const Signature& sig);
/**
* 创建方法符号
*/
MethodPtr CreateMethod(
const std::string& name,
const ast::Location& loc,
const Signature& sig,
Class* owner);
/**
* 创建构造函数符号
*/
ConstructorPtr CreateConstructor(
const std::string& name,
const ast::Location& loc,
const Signature& sig,
Class* owner);
/**
* 创建析构函数符号
*/
DestructorPtr CreateDestructor(
const std::string& name,
const ast::Location& loc,
Class* owner);
/**
* 创建属性符号
*/
PropertyPtr CreateProperty(
const std::string& name,
const ast::Location& loc,
const TypeInfo& type);
/**
* 创建类符号
*/
ClassPtr CreateClass(
const std::string& name,
const ast::Location& loc);
/**
* 创建 Unit 符号
*/
UnitPtr CreateUnit(const std::string& name, const ast::Location& loc);
// ==================== 便捷方法 ====================
/**
* 创建并插入变量
* @return 如果插入成功返回符号,否则返回 nullptr
*/
VariablePtr CreateAndInsert(Table* table, const std::string& name, Kind kind, const ast::Location& loc, const TypeInfo& type);
/**
* 从 AST 类型字符串创建变量
*/
VariablePtr CreateVariableFromAST(const std::string& name, Kind kind, const ast::Location& loc,
const std::optional<std::string>& type_str);
}
}
@@ -0,0 +1,74 @@
#include "./scope_manager.hpp"
namespace lsp::language::symbol
{
// ==================== ScopeGuard 实现 ====================
ScopeGuard::ScopeGuard(Table*& current, Table* new_scope) :
current_(current), previous_(current), active_(true)
{
current_ = new_scope;
}
ScopeGuard::~ScopeGuard()
{
if (active_)
{
current_ = previous_;
}
}
ScopeGuard::ScopeGuard(ScopeGuard&& other) noexcept :
current_(other.current_),
previous_(other.previous_),
active_(other.active_)
{
other.active_ = false;
}
ScopeGuard& ScopeGuard::operator=(ScopeGuard&& other) noexcept
{
if (this != &other)
{
if (active_)
{
current_ = previous_;
}
current_ = other.current_;
previous_ = other.previous_;
active_ = other.active_;
other.active_ = false;
}
return *this;
}
// ==================== ScopeManager 实现 ====================
ScopeManager::ScopeManager(Table* root) :
root_(root), current_(root)
{
}
Table* ScopeManager::Current() const
{
return current_;
}
ScopeGuard ScopeManager::EnterScope(Table* scope)
{
return ScopeGuard(current_, scope);
}
ScopeGuard ScopeManager::CreateAndEnterChild(ScopeKind kind)
{
Table* child = current_->CreateChild(kind);
return ScopeGuard(current_, child);
}
void ScopeManager::SetCurrent(Table* scope)
{
current_ = scope;
}
}
@@ -0,0 +1,53 @@
#pragma once
#include "../core/table.hpp"
namespace lsp::language::symbol
{
// ==================== 作用域守卫 ====================
// RAII风格的作用域管理
class ScopeGuard
{
public:
ScopeGuard(Table*& current, Table* new_scope);
~ScopeGuard();
ScopeGuard(const ScopeGuard&) = delete;
ScopeGuard& operator=(const ScopeGuard&) = delete;
ScopeGuard(ScopeGuard&& other) noexcept;
ScopeGuard& operator=(ScopeGuard&& other) noexcept;
private:
Table*& current_;
Table* previous_;
bool active_;
};
// ==================== 作用域管理器 ====================
// 负责管理当前作用域的切换和导航
class ScopeManager
{
public:
explicit ScopeManager(Table* root);
// 获取当前作用域
Table* Current() const;
// 进入指定作用域(返回守卫,自动恢复)
[[nodiscard]] ScopeGuard EnterScope(Table* scope);
// 创建子作用域并进入
[[nodiscard]] ScopeGuard CreateAndEnterChild(ScopeKind kind);
// 直接设置当前作用域(不推荐,破坏RAII)
void SetCurrent(Table* scope);
// 获取根作用域
Table* Root() const { return root_; }
private:
Table* root_;
Table* current_;
};
}
@@ -0,0 +1,145 @@
#include <sstream>
#include "./incremental.hpp"
namespace lsp::language::symbol
{
// ==================== SymbolCacheKey 实现 ====================
std::string SymbolCacheKey::ComputeSignatureHash(const Signature& sig)
{
std::ostringstream oss;
oss << sig.parameters.size() << "|";
for (const auto& param : sig.parameters)
{
oss << param.name << ":"
<< param.type.Annotation() << ":"
<< (param.is_var ? "v" : "")
<< (param.is_out ? "o" : "") << "|";
}
if (sig.return_type)
{
oss << "ret:" << sig.return_type->Annotation();
}
return oss.str();
}
// ==================== SymbolCache 实现 ====================
SymbolCache::SymbolCache(size_t max_size) :
max_size_(max_size)
{
}
const SymbolPtr* SymbolCache::Find(const SymbolCacheKey& key)
{
auto it = cache_.find(key);
if (it != cache_.end())
{
// 更新 LRU:移到最前面
TouchKey(key);
return &it->second.symbol;
}
return nullptr;
}
void SymbolCache::Insert(const SymbolCacheKey& key, const SymbolPtr& symbol)
{
// 检查是否已存在
auto it = cache_.find(key);
if (it != cache_.end())
{
// 更新现有条目
it->second.symbol = symbol;
TouchKey(key);
return;
}
// 检查是否需要淘汰
if (cache_.size() >= max_size_)
{
EvictLRU();
}
// 插入新条目
lru_list_.push_front(key);
cache_[key] = CacheEntry{ symbol, lru_list_.begin() };
}
void SymbolCache::Clear()
{
cache_.clear();
lru_list_.clear();
}
void SymbolCache::EvictLRU()
{
if (lru_list_.empty())
return;
// 删除最久未使用的项(列表末尾)
auto lru_key = lru_list_.back();
lru_list_.pop_back();
cache_.erase(lru_key);
}
void SymbolCache::TouchKey(const SymbolCacheKey& key)
{
auto it = cache_.find(key);
if (it == cache_.end())
return;
// 从当前位置删除
lru_list_.erase(it->second.lru_iter);
// 移到最前面
lru_list_.push_front(key);
it->second.lru_iter = lru_list_.begin();
}
SymbolCacheKey SymbolCache::MakeKey(const Symbol* symbol)
{
if (!symbol)
return SymbolCacheKey{};
SymbolCacheKey key;
key.symbol_name = symbol->name;
key.symbol_kind = symbol->kind;
key.declaration_line = symbol->location.start_line;
key.declaration_column = symbol->location.start_column;
// 对于函数,添加签名哈希
if (auto* func = dynamic_cast<const Function*>(symbol))
{
key.signature_hash = SymbolCacheKey::ComputeSignatureHash(func->signature);
}
else if (auto* ctor = dynamic_cast<const Constructor*>(symbol))
{
key.signature_hash = SymbolCacheKey::ComputeSignatureHash(ctor->signature);
}
return key;
}
SymbolCacheKey SymbolCache::MakeKeyFromAST(
const std::string& name,
Kind kind,
const ast::Location& name_location,
const std::optional<Signature>& signature)
{
SymbolCacheKey key;
key.symbol_name = name;
key.symbol_kind = kind;
key.declaration_line = name_location.start_line;
key.declaration_column = name_location.start_column;
if (signature)
{
key.signature_hash = SymbolCacheKey::ComputeSignatureHash(*signature);
}
return key;
}
}
@@ -0,0 +1,97 @@
#pragma once
#include <unordered_map>
#include <optional>
#include <list>
#include "../core/symbol.hpp"
namespace lsp::language::symbol
{
// ==================== 改进的缓存键设计 ====================
// 基于 AST 位置和内容,避免指针地址依赖
struct SymbolCacheKey
{
std::string symbol_name;
Kind symbol_kind;
uint32_t declaration_line; // 使用声明位置行号
uint32_t declaration_column; // 使用声明位置列号
std::optional<std::string> signature_hash; // 函数签名哈希
bool operator==(const SymbolCacheKey& other) const
{
return symbol_name == other.symbol_name &&
symbol_kind == other.symbol_kind &&
declaration_line == other.declaration_line &&
declaration_column == other.declaration_column &&
signature_hash == other.signature_hash;
}
// 生成签名哈希(用于函数/方法)
static std::string ComputeSignatureHash(const Signature& sig);
};
struct SymbolCacheKeyHash
{
size_t operator()(const SymbolCacheKey& key) const
{
size_t h1 = std::hash<std::string>()(key.symbol_name);
size_t h2 = std::hash<int>()(static_cast<int>(key.symbol_kind));
size_t h3 = std::hash<uint32_t>()(key.declaration_line);
size_t h4 = std::hash<uint32_t>()(key.declaration_column);
size_t h5 = key.signature_hash ?
std::hash<std::string>()(*key.signature_hash) :
0;
return h1 ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3) ^ (h5 << 4);
}
};
// ==================== 符号缓存管理器(带LRU ====================
class SymbolCache
{
public:
explicit SymbolCache(size_t max_size = 10000);
// 查找缓存
const SymbolPtr* Find(const SymbolCacheKey& key);
// 插入缓存
void Insert(const SymbolCacheKey& key, const SymbolPtr& symbol);
// 清空缓存
void Clear();
// 获取缓存大小
size_t Size() const { return cache_.size(); }
// 设置最大缓存大小
void SetMaxSize(size_t max_size) { max_size_ = max_size; }
// 从 Symbol 生成 Key
static SymbolCacheKey MakeKey(const Symbol* symbol);
// 从 AST 信息生成 Key
static SymbolCacheKey MakeKeyFromAST(
const std::string& name,
Kind kind,
const ast::Location& name_location,
const std::optional<Signature>& signature = std::nullopt);
private:
// LRU 淘汰策略
void EvictLRU();
void TouchKey(const SymbolCacheKey& key);
private:
struct CacheEntry
{
SymbolPtr symbol;
std::list<SymbolCacheKey>::iterator lru_iter;
};
std::unordered_map<SymbolCacheKey, CacheEntry, SymbolCacheKeyHash> cache_;
std::list<SymbolCacheKey> lru_list_; // 最近使用列表
size_t max_size_;
};
}
@@ -0,0 +1,344 @@
#include "../core/symbol.hpp"
#include "./incremental_engine.hpp"
namespace lsp::language::symbol
{
IncrementalEngine::IncrementalEngine() :
cache_(10000),
max_cache_size_(10000)
{
}
// ==================== 符号复用与缓存 ====================
bool IncrementalEngine::TryReuseSymbol(const ast::ASTNode& node, Table* scope, SymbolRegistry* registry)
{
return std::visit([this, scope, registry](auto&& arg) -> bool {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, std::monostate>)
{
return true;
}
else if constexpr (std::is_same_v<T, ast::VarDeclaration>)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kVariable, arg.name_location);
const SymbolPtr* cached = cache_.Find(key);
if (cached && *cached)
{
return scope->Insert(*cached);
}
return false;
}
else if constexpr (std::is_same_v<T, ast::GlobalDeclaration>)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kGlobalVariable, arg.name_location);
const SymbolPtr* cached = cache_.Find(key);
if (cached && *cached)
{
return scope->Insert(*cached);
}
return false;
}
else if constexpr (std::is_same_v<T, ast::StaticDeclaration>)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kStaticVariable, arg.name_location);
const SymbolPtr* cached = cache_.Find(key);
if (cached && *cached)
{
return scope->Insert(*cached);
}
return false;
}
else if constexpr (std::is_same_v<T, ast::ConstDeclaration>)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kConstant, arg.name_location);
const SymbolPtr* cached = cache_.Find(key);
if (cached && *cached)
{
return scope->Insert(*cached);
}
return false;
}
else if constexpr (std::is_same_v<T, ast::FunctionDefinition>)
{
// 创建签名用于缓存键
Signature sig;
for (const auto& param : arg.signature.parameters)
{
Signature::Param p;
p.name = param.name;
if (param.type_name)
{
p.type = TypeInfo(*param.type_name);
}
p.is_var = param.is_var;
p.is_out = param.is_out;
sig.parameters.push_back(p);
}
if (arg.signature.return_type)
{
sig.return_type = TypeInfo(*arg.signature.return_type);
}
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kFunction, arg.name_location, sig);
const SymbolPtr* cached = cache_.Find(key);
if (cached && *cached)
{
auto func = std::dynamic_pointer_cast<Function>(*cached);
if (func)
{
return scope->InsertFunction(func);
}
}
return false;
}
else if constexpr (std::is_same_v<T, ast::ClassDefinition>)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kClass, arg.name_location);
const SymbolPtr* cached = cache_.Find(key);
if (cached && *cached)
{
return scope->Insert(*cached);
}
return false;
}
else if constexpr (std::is_same_v<T, ast::UnitDefinition>)
{
// Unit 支持复用
if (registry)
{
return TryReuseUnit(arg, registry);
}
return false;
}
else
{
// 其他类型(Expression, Block 等)直接跳过
return true;
}
},
node);
}
bool IncrementalEngine::TryReuseUnit(
const ast::UnitDefinition& unit_ast,
SymbolRegistry* registry)
{
if (!registry)
return false;
auto key = SymbolCache::MakeKeyFromAST(
unit_ast.name, Kind::kUnit, unit_ast.name_location);
const SymbolPtr* cached = cache_.Find(key);
if (cached && *cached)
{
auto unit = std::dynamic_pointer_cast<Unit>(*cached);
if (unit)
{
// 尝试将缓存的 Unit 添加到 Registry
return registry->AddUnit(unit);
}
}
return false;
}
void IncrementalEngine::CacheSymbol(const ast::ASTNode& node, Table* scope)
{
std::visit([this, scope](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, ast::VarDeclaration> ||
std::is_same_v<T, ast::GlobalDeclaration> ||
std::is_same_v<T, ast::StaticDeclaration>)
{
auto result = scope->LookupLocal(arg.name);
if (result && result.symbol)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, result.symbol->kind, arg.name_location);
const auto& symbols = scope->Symbols();
auto it = symbols.find(arg.name);
if (it != symbols.end())
{
cache_.Insert(key, it->second);
}
}
}
else if constexpr (std::is_same_v<T, ast::ConstDeclaration>)
{
auto result = scope->LookupLocal(arg.name);
if (result && result.symbol)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kConstant, arg.name_location);
const auto& symbols = scope->Symbols();
auto it = symbols.find(arg.name);
if (it != symbols.end())
{
cache_.Insert(key, it->second);
}
}
}
else if constexpr (std::is_same_v<T, ast::FunctionDefinition>)
{
auto result = scope->LookupLocal(arg.name);
if (result && result.symbol)
{
// 创建签名用于缓存键
Signature sig;
for (const auto& param : arg.signature.parameters)
{
Signature::Param p;
p.name = param.name;
if (param.type_name)
{
p.type = TypeInfo(*param.type_name);
}
p.is_var = param.is_var;
p.is_out = param.is_out;
sig.parameters.push_back(p);
}
if (arg.signature.return_type)
{
sig.return_type = TypeInfo(*arg.signature.return_type);
}
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kFunction, arg.name_location, sig);
const auto& symbols = scope->Symbols();
auto it = symbols.find(arg.name);
if (it != symbols.end())
{
cache_.Insert(key, it->second);
}
}
}
else if constexpr (std::is_same_v<T, ast::ClassDefinition>)
{
auto result = scope->LookupLocal(arg.name);
if (result && result.symbol)
{
auto key = SymbolCache::MakeKeyFromAST(
arg.name, Kind::kClass, arg.name_location);
const auto& symbols = scope->Symbols();
auto it = symbols.find(arg.name);
if (it != symbols.end())
{
cache_.Insert(key, it->second);
}
}
}
else if constexpr (std::is_same_v<T, ast::UnitDefinition>)
{
// Unit 缓存需要从 Registry 获取
// 这里暂时不处理,在 BuildCache 中统一处理
}
// 其他类型不需要缓存
},
node);
}
void IncrementalEngine::BuildCache(const SymbolRegistry& registry)
{
// 缓存所有 Unit
for (const auto& [name, unit] : registry.Units())
{
auto key = SymbolCache::MakeKey(unit.get());
cache_.Insert(key, unit);
// 递归缓存 Unit 内部的符号
if (unit->interface_symbols)
CacheScopeRecursive(unit->interface_symbols.get());
if (unit->implementation_symbols)
CacheScopeRecursive(unit->implementation_symbols.get());
}
// 缓存全局作用域
CacheScopeRecursive(const_cast<Table*>(registry.GlobalScope()));
}
void IncrementalEngine::CacheScopeRecursive(Table* scope)
{
if (!scope)
return;
// 缓存当前作用域的所有符号
for (const auto& [name, symbol] : scope->Symbols())
{
auto key = SymbolCache::MakeKey(symbol.get());
cache_.Insert(key, symbol);
// 递归缓存类成员
if (auto* cls = dynamic_cast<Class*>(symbol.get()))
{
if (cls->members)
{
CacheScopeRecursive(cls->members.get());
}
}
// 递归缓存函数体作用域
if (auto* func = dynamic_cast<Function*>(symbol.get()))
{
if (func->body_scope)
{
CacheScopeRecursive(func->body_scope.get());
}
}
// 递归缓存构造函数体作用域
if (auto* ctor = dynamic_cast<Constructor*>(symbol.get()))
{
if (ctor->body_scope)
{
CacheScopeRecursive(ctor->body_scope.get());
}
}
// 递归缓存析构函数体作用域
if (auto* dtor = dynamic_cast<Destructor*>(symbol.get()))
{
if (dtor->body_scope)
{
CacheScopeRecursive(dtor->body_scope.get());
}
}
}
}
// ==================== 管理接口 ====================
void IncrementalEngine::Clear()
{
cache_.Clear();
}
void IncrementalEngine::SetMaxCacheSize(size_t max_size)
{
max_cache_size_ = max_size;
cache_.SetMaxSize(max_size);
}
size_t IncrementalEngine::GetCacheSize() const
{
return cache_.Size();
}
}
@@ -0,0 +1,75 @@
#pragma once
#include "../../ast/types.hpp"
#include "../core/registry.hpp"
#include "../core/table.hpp"
#include "./incremental.hpp"
namespace lsp::language::symbol
{
/**
* 增量构建引擎 - 管理符号缓存和复用
*
* 职责:
* - 管理符号缓存 (SymbolCache)
* - 提供符号复用接口
* - 提供符号缓存接口
* - 构建全局缓存
*
* 不负责:
* - 依赖追踪(移到语义分析阶段)
* - 类型解析(移到语义分析阶段)
*/
class IncrementalEngine
{
public:
IncrementalEngine();
// ==================== 符号复用与缓存 ====================
/**
* 尝试从缓存复用符号
* @param node AST 节点
* @param scope 当前作用域
* @param registry 符号注册表(用于 Unit 复用)
* @return 是否成功复用
*/
bool TryReuseSymbol(const ast::ASTNode& node, Table* scope, SymbolRegistry* registry = nullptr);
/**
* 缓存当前符号
* @param node AST 节点
* @param scope 当前作用域
*/
void CacheSymbol(const ast::ASTNode& node, Table* scope);
/**
* 从整个注册表构建缓存
* @param registry 符号注册表
*/
void BuildCache(const SymbolRegistry& registry);
// ==================== 管理接口 ====================
void Clear();
void SetMaxCacheSize(size_t max_size);
size_t GetCacheSize() const;
// 访问器
SymbolCache& GetCache() { return cache_; }
const SymbolCache& GetCache() const { return cache_; }
private:
// ==================== 内部辅助方法 ====================
// 递归缓存作用域中的所有符号
void CacheScopeRecursive(Table* scope);
// 尝试复用 Unit
bool TryReuseUnit(const ast::UnitDefinition& unit_ast, SymbolRegistry* registry);
private:
SymbolCache cache_;
size_t max_cache_size_;
};
}
@@ -0,0 +1,59 @@
#include "./type.hpp"
#include <sstream>
#include <cctype>
namespace lsp::language::symbol
{
// ==================== TypeFactory 实现 ====================
TypeInfo TypeFactory::FromAnnotation(const std::string& annotation)
{
// 直接存储原始注解字符串,不做任何解析
// 类型引用的解析将在语义分析阶段完成
return TypeInfo(Trim(annotation));
}
std::string TypeFactory::Trim(const std::string& str)
{
size_t start = 0;
while (start < str.length() && std::isspace(static_cast<unsigned char>(str[start])))
++start;
if (start == str.length())
return "";
size_t end = str.length();
while (end > start && std::isspace(static_cast<unsigned char>(str[end - 1])))
--end;
return str.substr(start, end - start);
}
// ==================== TypeFormatter 实现 ====================
std::string TypeFormatter::ToString(const TypeInfo& type)
{
if (!type.HasAnnotation())
return "<no annotation>";
return type.Annotation();
}
std::string TypeFormatter::ToDebugString(const TypeInfo& type)
{
std::ostringstream oss;
oss << "TypeInfo { ";
if (type.HasAnnotation())
{
oss << "annotation: \"" << type.Annotation() << "\"";
}
else
{
oss << "no annotation";
}
oss << " }";
return oss.str();
}
}
@@ -0,0 +1,57 @@
#pragma once
#include <string>
#include "../core/symbol.hpp"
namespace lsp::language::symbol
{
// ==================== 类型工厂 ====================
/**
* 类型工厂 - 仅用于符号表构建
*
* 职责:
* - 从类型注解字符串创建 TypeInfo
* - 存储原始字符串,不解析任何引用
*
* 不负责:
* - 类型引用解析(属于语义分析)
* - 表达式解析(属于语义分析)
* - 类型检查(属于语义分析)
*/
class TypeFactory
{
public:
/**
* 从类型注解创建 TypeInfo
* @param annotation 类型注解字符串(如 "Integer", "TMyClass"
* @return TypeInfo 对象
*
* 注意:直接存储原始字符串,不做任何解析
*/
static TypeInfo FromAnnotation(const std::string& annotation);
private:
// 辅助函数:去除首尾空格
static std::string Trim(const std::string& str);
};
// ==================== 类型格式化器 ====================
/**
* 类型格式化器 - 用于调试和日志输出
*/
class TypeFormatter
{
public:
/**
* 转换为可读字符串
*/
static std::string ToString(const TypeInfo& type);
/**
* 转换为调试字符串(包含详细信息)
*/
static std::string ToDebugString(const TypeInfo& type);
};
}