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