Files
tsl-devkit/lsp-server/src/language/symbol/collector/context.hpp
T
2025-10-15 20:31:00 +08:00

101 lines
3.5 KiB
C++

#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);
}
}
};
}