From b82d5d147f4dfa1b1594d182028e89c0a16ee5cc Mon Sep 17 00:00:00 2001 From: Safi Date: Sat, 16 May 2026 20:20:49 +0100 Subject: [PATCH] fix review findings from #898 #895 #899 corrections - Revert .h -> extract_c (C++ grammar rejects C++ keywords used as identifiers in Linux-kernel-style headers; .hpp/.hxx/.hh already route to extract_cpp) - Fix field_declaration block: use children_by_field_name("declarator") instead of iterating all children with wrong type guard; replace ensure_node (undefined) with add_node - Fix _import_c include resolution: use _make_id(str(resolved)) to match the file_nid scheme _extract_generic uses, not _make_id(_file_stem(resolved)) - Fix exact_merges counter in dedup Pass 1 to count only within-file merges actually performed, not the raw unpartitioned group sizes Co-Authored-By: Claude Sonnet 4.6 --- graphify/dedup.py | 4 ++-- graphify/extract.py | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/graphify/dedup.py b/graphify/dedup.py index b0abe628d..5c15f33f5 100644 --- a/graphify/dedup.py +++ b/graphify/dedup.py @@ -174,6 +174,7 @@ def deduplicate_entities( norm_to_nodes[key].append(node) uf = _UF() + exact_merges = 0 for key, group in norm_to_nodes.items(): if len(group) <= 1: continue @@ -188,8 +189,7 @@ def deduplicate_entities( winner = _pick_winner(file_group) for node in file_group: uf.union(winner["id"], node["id"]) - - exact_merges = sum(len(g) - 1 for g in norm_to_nodes.values() if len(g) > 1) + exact_merges += len(file_group) - 1 # ── pass 2: MinHash/LSH + Jaro-Winkler (high-entropy nodes only) ───────── candidates: list[dict] = [] diff --git a/graphify/extract.py b/graphify/extract.py index 720920464..3903f431c 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -560,7 +560,7 @@ def _import_c(node, source: bytes, file_nid: str, stem: str, edges: list, str_pa if child.type != "system_lib_string": resolved = _resolve_c_include_path(raw, str_path) if resolved is not None: - tgt_nid = _make_id(_file_stem(resolved)) + tgt_nid = _make_id(str(resolved)) edges.append({ "source": file_nid, "target": tgt_nid, @@ -1495,16 +1495,17 @@ def _extract_generic(path: Path, config: LanguageConfig) -> dict: if (config.ts_module == "tree_sitter_cpp" and t == "field_declaration" and parent_class_nid): - # Emit a node for each field declarator so methods declared - # inside a class body are visible in the graph. - for child in node.children: - if child.type != "field_declarator": - continue - name = _get_cpp_func_name(child, source) + # Emit a node for each data member. Use children_by_field_name so we + # only visit declarator children, not the type node (which would give + # us the type name, not the field name). Handles int x, y; via + # multiple declarator fields and static const int MAX = 100; via the + # init_declarator → field_identifier recursion in _get_cpp_func_name. + for decl in node.children_by_field_name("declarator"): + name = _get_cpp_func_name(decl, source) if name: - line = child.start_point[0] + 1 + line = decl.start_point[0] + 1 field_nid = _make_id(parent_class_nid, name) - ensure_node(field_nid, name, line) + add_node(field_nid, name, line) add_edge(parent_class_nid, field_nid, "defines", line, context="field") return @@ -6081,7 +6082,7 @@ _DISPATCH: dict[str, Any] = { ".groovy": extract_groovy, ".gradle": extract_groovy, ".c": extract_c, - ".h": extract_cpp, + ".h": extract_c, ".cpp": extract_cpp, ".cc": extract_cpp, ".cxx": extract_cpp,