brokk_bifrost_python/graph/
hits.rs1use crate::graph::extractor::ScanCtx;
2use brokk_bifrost_core::analyzer::Range;
3use brokk_bifrost_core::analyzer::usages::common::{
4 SNIPPET_CONTEXT_LINES, reclassify_self_receiver_hit_at, usage_hit,
5};
6use brokk_bifrost_core::text_utils::{find_line_index_for_offset, trimmed_snippet_around_line};
7use tree_sitter::Node;
8
9pub fn record_hit(node: Node<'_>, ctx: &mut ScanCtx<'_>) {
10 if let Some(hit) = build_hit(node, ctx) {
11 ctx.hits.insert(hit);
12 }
13}
14
15pub fn record_unproven_hit(node: Node<'_>, ctx: &mut ScanCtx<'_>) {
16 if let Some(hit) = build_hit(node, ctx) {
17 ctx.unproven_hits.insert(hit.into_unproven());
18 }
19}
20
21pub fn record_self_receiver_hit(node: Node<'_>, ctx: &mut ScanCtx<'_>) {
27 record_hit(node, ctx);
28 reclassify_self_receiver_hit_at(ctx.hits, ctx.file, node.start_byte(), node.end_byte());
29}
30
31pub fn record_import_hit(node: Node<'_>, ctx: &mut ScanCtx<'_>) {
35 if let Some(hit) = build_hit(node, ctx) {
36 ctx.hits.insert(hit.into_import());
37 }
38}
39
40fn build_hit(
41 node: Node<'_>,
42 ctx: &mut ScanCtx<'_>,
43) -> Option<brokk_bifrost_core::analyzer::usages::model::UsageHit> {
44 let start_byte = node.start_byte();
45 let end_byte = node.end_byte();
46 if start_byte >= end_byte {
47 return None;
48 }
49
50 let line_idx = find_line_index_for_offset(ctx.line_starts, start_byte);
51 let snippet =
52 trimmed_snippet_around_line(ctx.source, ctx.line_starts, line_idx, SNIPPET_CONTEXT_LINES);
53 let range = Range {
54 start_byte,
55 end_byte,
56 start_line: line_idx,
57 end_line: line_idx,
58 };
59
60 let enclosing = ctx.graph.index.enclosing_code_unit(ctx.file, &range)?;
61
62 Some(usage_hit(
63 ctx.file, line_idx, start_byte, end_byte, enclosing, snippet,
64 ))
65}