use crate::syntax::ruby_semantic_identifier_range;
use brokk_bifrost_core::analyzer::model::Range;
use brokk_bifrost_core::analyzer::usages::common::{
SNIPPET_CONTEXT_LINES, reclassify_self_receiver_hit_at, usage_hit,
};
use brokk_bifrost_core::analyzer::usages::model::UsageHit;
use brokk_bifrost_core::analyzer::{CodeUnitIndex, ProjectFile};
use brokk_bifrost_core::text_utils::{find_line_index_for_offset, trimmed_snippet_around_line};
use std::collections::BTreeSet;
use tree_sitter::Node;
pub fn record_usage_hit(
index: &dyn CodeUnitIndex,
file: &ProjectFile,
source: &str,
line_starts: &[usize],
hits: &mut BTreeSet<UsageHit>,
node: Node<'_>,
) {
let range = ruby_semantic_identifier_range(node, source);
let start_byte = range.start_byte;
let end_byte = range.end_byte;
if start_byte >= end_byte {
return;
}
let line_idx = find_line_index_for_offset(line_starts, start_byte);
let snippet = trimmed_snippet_around_line(source, line_starts, line_idx, SNIPPET_CONTEXT_LINES);
let enclosing_range = Range {
start_byte,
end_byte,
start_line: line_idx,
end_line: line_idx,
};
let Some(enclosing) = index.enclosing_code_unit(file, &enclosing_range) else {
return;
};
hits.insert(usage_hit(
file, line_idx, start_byte, end_byte, enclosing, snippet,
));
}
pub fn record_self_receiver_usage_hit(
index: &dyn CodeUnitIndex,
file: &ProjectFile,
source: &str,
line_starts: &[usize],
hits: &mut BTreeSet<UsageHit>,
node: Node<'_>,
) {
record_usage_hit(index, file, source, line_starts, hits, node);
let range = ruby_semantic_identifier_range(node, source);
reclassify_self_receiver_hit_at(hits, file, range.start_byte, range.end_byte);
}
pub fn record_unproven_usage_hit(
index: &dyn CodeUnitIndex,
file: &ProjectFile,
source: &str,
line_starts: &[usize],
hits: &mut BTreeSet<UsageHit>,
node: Node<'_>,
) {
let range = ruby_semantic_identifier_range(node, source);
let start_byte = range.start_byte;
let end_byte = range.end_byte;
if start_byte >= end_byte {
return;
}
let line_idx = find_line_index_for_offset(line_starts, start_byte);
let snippet = trimmed_snippet_around_line(source, line_starts, line_idx, SNIPPET_CONTEXT_LINES);
let enclosing_range = Range {
start_byte,
end_byte,
start_line: line_idx,
end_line: line_idx,
};
let Some(enclosing) = index.enclosing_code_unit(file, &enclosing_range) else {
return;
};
hits.insert(
usage_hit(file, line_idx, start_byte, end_byte, enclosing, snippet).into_unproven(),
);
}