重构语法树/符号表
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user