mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-18 13:53:01 +08:00
fix(dart): a bare call stays in the class hierarchy (#2145)
A receiver-less Dart call now reaches only a method of the enclosing class, something it extends / mixes in / implements, or an extension on one of those types, and the nearest one wins. The hierarchy is read from each declaration's head (comments and type arguments dropped), since supertype edges don't exist on the first pass. Body-less abstract members (extracted as owned functions) are scoped too. Mixin-application classes (`class A = B with C;`) were extracted as `<anonymous>` with no supertypes; both the wasm extractor and the Rust kernel now name them and emit their extends/implements refs (kernel parity verified on bloc, riverpod, shelf, dio, getx). A/B (edges removed / added): riverpod -1945/+517, shelf -785, getx -855/+18, bloc -178/+95, dio -78. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -567,6 +567,18 @@ impl<'t> Walker<'t> {
|
||||
return ctor_name;
|
||||
}
|
||||
}
|
||||
// `class A = B with C;` — the mixin application's own identifier.
|
||||
if node.kind() == "class_definition" {
|
||||
let mut cursor = node.walk();
|
||||
let application = node.named_children(&mut cursor).find(|c| c.kind() == "mixin_application_class");
|
||||
if let Some(application) = application {
|
||||
let mut ac = application.walk();
|
||||
let id = application.named_children(&mut ac).find(|c| c.kind() == "identifier");
|
||||
if let Some(id) = id {
|
||||
return self.text(id).to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(name_node) = node.child_by_field_name("name") {
|
||||
return self.text(name_node).to_string();
|
||||
}
|
||||
@@ -1181,7 +1193,34 @@ impl<'t> Walker<'t> {
|
||||
let mut cursor = node.walk();
|
||||
let kids: Vec<Node<'t>> = node.named_children(&mut cursor).collect();
|
||||
for child in kids {
|
||||
if child.kind() == "superclass" {
|
||||
if child.kind() == "mixin_application_class" {
|
||||
// `class A = B with M implements I;` — extends B, implements
|
||||
// each mixin and interface, in source order.
|
||||
let mut cc = child.walk();
|
||||
let application = child.named_children(&mut cc).find(|c| c.kind() == "mixin_application");
|
||||
let Some(application) = application else { continue };
|
||||
let mut ac = application.walk();
|
||||
let parts: Vec<Node<'t>> = application.named_children(&mut ac).collect();
|
||||
for t in parts {
|
||||
match t.kind() {
|
||||
"type_identifier" => {
|
||||
let name = self.text(t).to_string();
|
||||
self.push_ref_at(class_row, &name, "extends", t);
|
||||
}
|
||||
"mixins" | "interfaces" => {
|
||||
let mut mc = t.walk();
|
||||
let targets: Vec<Node<'t>> = t.named_children(&mut mc).collect();
|
||||
for m in targets {
|
||||
if t.kind() == "interfaces" || m.kind() == "type_identifier" {
|
||||
let name = self.text(m).to_string();
|
||||
self.push_ref_at(class_row, &name, "implements", m);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
} else if child.kind() == "superclass" {
|
||||
// extends type + `with` mixins (implements) — dart branch.
|
||||
let mut cc = child.walk();
|
||||
let targets: Vec<Node<'t>> = child.named_children(&mut cc).collect();
|
||||
|
||||
Reference in New Issue
Block a user