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