mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-22 17:48:44 +08:00
merge: current upstream main into initializer-walk work
This commit is contained in:
@@ -77,7 +77,7 @@ pub const EDGE_ROW_SIZE: usize = 44;
|
||||
pub const REF_ROW_SIZE: usize = 40;
|
||||
|
||||
/// Mirror of NODE_KINDS in src/types.ts — order is the wire contract.
|
||||
pub const NODE_KINDS: [&str; 22] = [
|
||||
pub const NODE_KINDS: [&str; 23] = [
|
||||
"file",
|
||||
"module",
|
||||
"class",
|
||||
@@ -100,6 +100,7 @@ pub const NODE_KINDS: [&str; 22] = [
|
||||
"export",
|
||||
"route",
|
||||
"component",
|
||||
"union",
|
||||
];
|
||||
|
||||
/// Mirror of EDGE_KINDS in src/types.ts — order is the wire contract.
|
||||
|
||||
@@ -455,7 +455,7 @@ impl<'t> Walker<'t> {
|
||||
fn inside_class_like(&self) -> bool {
|
||||
self.stack
|
||||
.last()
|
||||
.map(|s| matches!(s.kind, "class" | "struct" | "interface" | "trait" | "enum" | "module"))
|
||||
.map(|s| matches!(s.kind, "class" | "struct" | "union" | "interface" | "trait" | "enum" | "module"))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ impl<'t> Walker<'t> {
|
||||
let parent_ok = self
|
||||
.stack
|
||||
.last()
|
||||
.map(|s| matches!(s.kind, "file" | "class" | "module" | "struct" | "enum"))
|
||||
.map(|s| matches!(s.kind, "file" | "class" | "module" | "struct" | "union" | "enum"))
|
||||
.unwrap_or(false);
|
||||
if parent_ok {
|
||||
self.fs_values.insert(name.to_string(), row);
|
||||
@@ -813,7 +813,10 @@ impl<'t> Walker<'t> {
|
||||
self.extract_class(node);
|
||||
skip_children = true;
|
||||
} else if kind == "struct_specifier" {
|
||||
self.extract_struct(node);
|
||||
self.extract_aggregate(node, "struct");
|
||||
skip_children = true;
|
||||
} else if kind == "union_specifier" {
|
||||
self.extract_aggregate(node, "union");
|
||||
skip_children = true;
|
||||
} else if kind == "enum_specifier" {
|
||||
self.extract_enum(node);
|
||||
@@ -925,7 +928,7 @@ impl<'t> Walker<'t> {
|
||||
.iter()
|
||||
.position(|m| {
|
||||
m.name == *receiver_type
|
||||
&& matches!(m.kind, "struct" | "class" | "enum" | "trait")
|
||||
&& matches!(m.kind, "struct" | "union" | "class" | "enum" | "trait")
|
||||
})
|
||||
.map(|i| i as u32);
|
||||
if let Some(owner_row) = owner_row {
|
||||
@@ -971,8 +974,8 @@ impl<'t> Walker<'t> {
|
||||
self.stack.pop();
|
||||
}
|
||||
|
||||
/// extractStruct: bodiless specifiers (fwd decls / elaborated refs) skip.
|
||||
fn extract_struct(&mut self, node: Node<'t>) {
|
||||
/// Extract a struct-like declaration while preserving its semantic kind.
|
||||
fn extract_aggregate(&mut self, node: Node<'t>, kind: &'static str) {
|
||||
let Some(body) = node.child_by_field_name("body") else { return };
|
||||
let name = self.extract_name(node);
|
||||
let extra = Extra {
|
||||
@@ -980,9 +983,9 @@ impl<'t> Walker<'t> {
|
||||
visibility: if self.variant == Variant::Cpp { self.visibility_of(node) } else { None },
|
||||
..Extra::default()
|
||||
};
|
||||
let Some(row) = self.create_node("struct", &name, node, extra) else { return };
|
||||
let Some(row) = self.create_node(kind, &name, node, extra) else { return };
|
||||
self.extract_inheritance(node, row);
|
||||
self.stack.push(Scope { row, kind: "struct", name });
|
||||
self.stack.push(Scope { row, kind, name });
|
||||
for i in 0..body.named_child_count() {
|
||||
if let Some(c) = body.named_child(i) {
|
||||
self.visit_node(c);
|
||||
@@ -1045,21 +1048,27 @@ impl<'t> Walker<'t> {
|
||||
resolved = Some("struct");
|
||||
break;
|
||||
}
|
||||
if child.kind() == "union_specifier" && child.child_by_field_name("body").is_some() {
|
||||
resolved = Some("union");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if resolved == Some("struct") {
|
||||
if matches!(resolved, Some("struct") | Some("union")) {
|
||||
let kind = resolved.unwrap();
|
||||
let Some(row) = self.create_node(
|
||||
"struct",
|
||||
kind,
|
||||
&name,
|
||||
node,
|
||||
Extra { docstring, ..Extra::default() },
|
||||
) else {
|
||||
return true;
|
||||
};
|
||||
self.stack.push(Scope { row, kind: "struct", name });
|
||||
self.stack.push(Scope { row, kind, name });
|
||||
let type_child = node
|
||||
.child_by_field_name("type")
|
||||
.or_else(|| self.find_child_by_kind(node, "struct_specifier"));
|
||||
.or_else(|| self.find_child_by_kind(node, "struct_specifier"))
|
||||
.or_else(|| self.find_child_by_kind(node, "union_specifier"));
|
||||
if let Some(tc) = type_child {
|
||||
self.extract_inheritance(tc, row);
|
||||
let body = tc.child_by_field_name("body").unwrap_or(tc);
|
||||
@@ -1557,7 +1566,11 @@ impl<'t> Walker<'t> {
|
||||
return;
|
||||
}
|
||||
if kind == "struct_specifier" {
|
||||
self.extract_struct(node);
|
||||
self.extract_aggregate(node, "struct");
|
||||
return;
|
||||
}
|
||||
if kind == "union_specifier" {
|
||||
self.extract_aggregate(node, "union");
|
||||
return;
|
||||
}
|
||||
if kind == "enum_specifier" {
|
||||
|
||||
@@ -432,8 +432,19 @@ struct InlineScan {
|
||||
fn scan_inline_structs(s: &[u8]) -> InlineScan {
|
||||
let mut out = InlineScan { ptr: false, types: Vec::new(), tags: Vec::new() };
|
||||
let mut last = 0;
|
||||
while let Some(t) = find_word(s, b"struct", last) {
|
||||
let after_kw = t + 6;
|
||||
loop {
|
||||
let next_struct = find_word(s, b"struct", last);
|
||||
let next_union = find_word(s, b"union", last);
|
||||
let Some((t, keyword_len)) = (match (next_struct, next_union) {
|
||||
(Some(st), Some(un)) if st < un => Some((st, 6)),
|
||||
(Some(_), Some(un)) => Some((un, 5)),
|
||||
(Some(st), None) => Some((st, 6)),
|
||||
(None, Some(un)) => Some((un, 5)),
|
||||
(None, None) => None,
|
||||
}) else {
|
||||
break;
|
||||
};
|
||||
let after_kw = t + keyword_len;
|
||||
let ws = skip_jsws(s, after_kw);
|
||||
if ws == after_kw || !is_word_at(s, ws) {
|
||||
last = t + 1;
|
||||
@@ -569,10 +580,10 @@ fn init_body(s: &[u8], p: usize) -> Option<(String, usize)> {
|
||||
let i = skip_jsws(s, p);
|
||||
let mods = modifier_positions(s, i);
|
||||
for &pos in mods.iter().rev() {
|
||||
for with_struct in [true, false] {
|
||||
let q = if with_struct {
|
||||
if s.len() >= pos + 6 && &s[pos..pos + 6] == b"struct" {
|
||||
let e = pos + 6;
|
||||
for keyword in [Some(b"struct".as_slice()), Some(b"union".as_slice()), None] {
|
||||
let q = if let Some(keyword) = keyword {
|
||||
if s.len() >= pos + keyword.len() && &s[pos..pos + keyword.len()] == keyword {
|
||||
let e = pos + keyword.len();
|
||||
let w = skip_jsws(s, e);
|
||||
if w == e {
|
||||
continue;
|
||||
@@ -729,12 +740,19 @@ fn alias_line(line: &[u8]) -> Option<&[u8]> {
|
||||
if v0 == name_end {
|
||||
return None; // [ \t]+ before the value
|
||||
}
|
||||
// (?:struct[ \t]+)* greedy, k-descending on value failure.
|
||||
// (?:(?:struct|union)[ \t]+)* greedy, k-descending on value failure.
|
||||
let mut stack = vec![v0];
|
||||
loop {
|
||||
let cur = *stack.last().unwrap();
|
||||
if line.len() >= cur + 6 && &line[cur..cur + 6] == b"struct" {
|
||||
let e = cur + 6;
|
||||
let keyword_len = if line.len() >= cur + 6 && &line[cur..cur + 6] == b"struct" {
|
||||
Some(6)
|
||||
} else if line.len() >= cur + 5 && &line[cur..cur + 5] == b"union" {
|
||||
Some(5)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(keyword_len) = keyword_len {
|
||||
let e = cur + keyword_len;
|
||||
let w2 = skip_sp_tab(line, e);
|
||||
if w2 > e {
|
||||
stack.push(w2);
|
||||
|
||||
@@ -217,7 +217,7 @@ impl<'t> Walker<'t> {
|
||||
fn inside_class_like(&self) -> bool {
|
||||
self.stack
|
||||
.last()
|
||||
.map(|s| matches!(s.kind, "class" | "struct" | "interface" | "trait" | "enum" | "module"))
|
||||
.map(|s| matches!(s.kind, "class" | "struct" | "union" | "interface" | "trait" | "enum" | "module"))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ impl<'t> Walker<'t> {
|
||||
let parent_ok = self
|
||||
.stack
|
||||
.last()
|
||||
.map(|s| matches!(s.kind, "file" | "class" | "module" | "struct" | "enum"))
|
||||
.map(|s| matches!(s.kind, "file" | "class" | "module" | "struct" | "union" | "enum"))
|
||||
.unwrap_or(false);
|
||||
if parent_ok {
|
||||
self.fs_values.insert(name.to_string(), row);
|
||||
@@ -447,7 +447,10 @@ impl<'t> Walker<'t> {
|
||||
self.extract_interface(node);
|
||||
skip_children = true;
|
||||
} else if kind == "struct_item" {
|
||||
self.extract_struct(node);
|
||||
self.extract_aggregate(node, "struct");
|
||||
skip_children = true;
|
||||
} else if kind == "union_item" {
|
||||
self.extract_aggregate(node, "union");
|
||||
skip_children = true;
|
||||
} else if kind == "enum_item" {
|
||||
self.extract_enum(node);
|
||||
@@ -529,7 +532,7 @@ impl<'t> Walker<'t> {
|
||||
.iter()
|
||||
.position(|m| {
|
||||
m.name == *receiver
|
||||
&& matches!(m.kind, "struct" | "class" | "enum" | "trait")
|
||||
&& matches!(m.kind, "struct" | "union" | "class" | "enum" | "trait")
|
||||
})
|
||||
.map(|i| i as u32);
|
||||
if let Some(owner_row) = owner_row {
|
||||
@@ -579,9 +582,8 @@ impl<'t> Walker<'t> {
|
||||
self.stack.pop();
|
||||
}
|
||||
|
||||
/// extractStruct — body field REQUIRED (unit structs mint no node; tuple
|
||||
/// structs' ordered_field_declaration_list is a body).
|
||||
fn extract_struct(&mut self, node: Node<'t>) {
|
||||
/// Extract a Rust struct or union with a body; unit structs remain skipped.
|
||||
fn extract_aggregate(&mut self, node: Node<'t>, kind: &'static str) {
|
||||
let Some(body) = node.child_by_field_name("body") else { return };
|
||||
let name = self.extract_name(node);
|
||||
let extra = Extra {
|
||||
@@ -589,10 +591,10 @@ impl<'t> Walker<'t> {
|
||||
visibility: Some(self.visibility_of(node)),
|
||||
..Extra::default()
|
||||
};
|
||||
let Some(row) = self.create_node("struct", &name, node, extra) else { return };
|
||||
let Some(row) = self.create_node(kind, &name, node, extra) else { return };
|
||||
self.extract_inheritance(node, row);
|
||||
|
||||
self.stack.push(Scope { row, kind: "struct", name });
|
||||
self.stack.push(Scope { row, kind, name });
|
||||
for i in 0..body.named_child_count() {
|
||||
if let Some(c) = body.named_child(i) {
|
||||
self.visit_node(c);
|
||||
@@ -1079,7 +1081,7 @@ impl<'t> Walker<'t> {
|
||||
let target_row = self
|
||||
.nodes_meta
|
||||
.iter()
|
||||
.position(|m| m.name == type_name && matches!(m.kind, "struct" | "enum" | "class"))
|
||||
.position(|m| m.name == type_name && matches!(m.kind, "struct" | "union" | "enum" | "class"))
|
||||
.map(|i| i as u32);
|
||||
if let Some(target_row) = target_row {
|
||||
self.push_ref_at(target_row, &trait_name, edge_kind_index("implements").unwrap(), trait_node);
|
||||
@@ -1153,7 +1155,11 @@ impl<'t> Walker<'t> {
|
||||
|
||||
// Structural nodes inside bodies.
|
||||
if kind == "struct_item" {
|
||||
self.extract_struct(node);
|
||||
self.extract_aggregate(node, "struct");
|
||||
return;
|
||||
}
|
||||
if kind == "union_item" {
|
||||
self.extract_aggregate(node, "union");
|
||||
return;
|
||||
}
|
||||
if kind == "enum_item" {
|
||||
|
||||
Reference in New Issue
Block a user