88 lines
2.4 KiB
C++
88 lines
2.4 KiB
C++
#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<size_t> 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());
|
|
}
|
|
}
|