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