Skip to content

Commit 6e547c2

Browse files
committed
feat(analyzer): extract parent scope for methods inside impl/class/trait
1 parent 1546340 commit 6e547c2

5 files changed

Lines changed: 52 additions & 1 deletion

File tree

src/domain/symbol.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ pub struct CodeSymbol {
5252
/// e.g., "pub fn connect(host: &str, timeout: Duration) -> Result<Connection>"
5353
/// None for languages or constructs where signature extraction isn't supported.
5454
pub signature: Option<String>,
55+
/// Parent scope name (e.g., "CommitValidator" for methods inside `impl CommitValidator`).
56+
/// None for top-level definitions.
57+
pub parent_scope: Option<String>,
5558
}
5659

5760
impl CodeSymbol {
@@ -74,10 +77,16 @@ impl std::fmt::Display for CodeSymbol {
7477
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7578
let action = if self.is_added { "+" } else { "-" };
7679
if let Some(sig) = &self.signature {
80+
let scope_prefix = self
81+
.parent_scope
82+
.as_ref()
83+
.map(|s| format!("{s} > "))
84+
.unwrap_or_default();
7785
write!(
7886
f,
79-
"[{}] {} ({}:{})",
87+
"[{}] {}{} ({}:{})",
8088
action,
89+
scope_prefix,
8190
sig,
8291
self.file.display(),
8392
self.line

src/eval.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ struct SymbolDef {
140140
is_whitespace_only: Option<bool>,
141141
#[serde(default)]
142142
signature: Option<String>,
143+
#[serde(default)]
144+
parent_scope: Option<String>,
143145
}
144146

145147
fn default_line() -> usize {
@@ -515,6 +517,7 @@ impl EvalRunner {
515517
is_added: def.is_added,
516518
is_whitespace_only: def.is_whitespace_only,
517519
signature: def.signature,
520+
parent_scope: def.parent_scope,
518521
})
519522
.collect()
520523
}

src/services/analyzer.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,8 @@ impl AnalyzerService {
334334

335335
let signature = Self::extract_signature(def_node, source);
336336

337+
let parent_scope = Self::extract_parent_scope(def_node, source);
338+
337339
if let Some(kind) = kind {
338340
symbols.push(CodeSymbol {
339341
kind,
@@ -345,6 +347,7 @@ impl AnalyzerService {
345347
is_added,
346348
is_whitespace_only: None,
347349
signature,
350+
parent_scope,
348351
});
349352
}
350353
}
@@ -498,6 +501,40 @@ impl AnalyzerService {
498501
}
499502
}
500503

504+
/// Walk up the AST to find the enclosing scope (impl, class, trait).
505+
/// Skips intermediate wrapper nodes like `declaration_list`, `class_body`, etc.
506+
fn extract_parent_scope(node: tree_sitter::Node, source: &str) -> Option<String> {
507+
let mut current = node.parent();
508+
while let Some(parent) = current {
509+
match parent.kind() {
510+
"impl_item" | "impl_block" => {
511+
// Rust: impl Type { fn method() }
512+
return parent
513+
.child_by_field_name("type")
514+
.and_then(|t| t.utf8_text(source.as_bytes()).ok())
515+
.map(|s| s.to_string());
516+
}
517+
"class_declaration" | "class_definition" | "class" | "class_specifier" => {
518+
// Most languages: class Foo { method() }
519+
return parent
520+
.child_by_field_name("name")
521+
.and_then(|n| n.utf8_text(source.as_bytes()).ok())
522+
.map(|s| s.to_string());
523+
}
524+
"trait_item" => {
525+
return parent
526+
.child_by_field_name("name")
527+
.and_then(|n| n.utf8_text(source.as_bytes()).ok())
528+
.map(|s| s.to_string());
529+
}
530+
_ => {
531+
current = parent.parent();
532+
}
533+
}
534+
}
535+
None
536+
}
537+
501538
/// Check if a C# node has a `modifier` child with text "public"
502539
fn has_csharp_public_modifier(node: tree_sitter::Node) -> bool {
503540
let child_count = node.child_count();

tests/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fn make_symbol(
3434
is_added,
3535
is_whitespace_only: None,
3636
signature: None,
37+
parent_scope: None,
3738
}
3839
}
3940

tests/splitter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ fn make_symbol(
2929
is_added,
3030
is_whitespace_only: None,
3131
signature: None,
32+
parent_scope: None,
3233
}
3334
}
3435

0 commit comments

Comments
 (0)