Problem
The Go AST extractor produces disconnected nodes for files that only contain methods on types defined in other files within the same package. This causes graphify to report these files as orphans when they're actually heavily used.
In a large Go codebase, graphify reported 12 files as orphaned with zero edges. Manual grep revealed that methods in those files have 34+ callers — they're some of the most-used code in the project.
Root Cause
1. Method receiver type nodes are file-scoped, not package-scoped
extract_go() at line ~1238:
parent_nid = _make_id(stem, receiver_type)
If a type is defined in foo.go but has methods in bar.go and baz.go, each file creates its own type node with a different ID. These are separate disconnected nodes in the graph, not one canonical type.
2. Call resolution is single-file only
label_to_nid (line ~1290) is built from nodes extracted from the current file only. When one file calls a method defined in another file within the same package, the call resolver can't find it because it only searches the current file's label map.
This means all cross-file method calls within a Go package are invisible to the graph.
Impact
- Files with only method definitions appear as orphans (zero edges)
- The god-nodes analysis misses heavily-called methods
- Community detection can't cluster types with their methods across files
- Dead code detection (zero-degree nodes) produces false positives
Suggested Fix
For type node IDs
Use the package path + type name instead of file stem + type name:
# Instead of: _make_id(stem, receiver_type)
# Use: _make_id(package_path, receiver_type)
Where package_path is derived from the directory. All methods on a type across all files in the same package would share one node.
For cross-file call resolution
Run extraction in two passes:
- Per-file pass: Extract all nodes (functions, methods, types) from each file
- Per-package pass: Build a combined
label_to_nid map for all files sharing a Go package, then resolve calls against the full map
This mirrors how Go itself resolves identifiers — package-scoped, not file-scoped.
Environment
- graphify v0.3.12 via pipx
- Large Go codebase (500+ files)
- tree-sitter-go via graphify's bundled parser
Problem
The Go AST extractor produces disconnected nodes for files that only contain methods on types defined in other files within the same package. This causes graphify to report these files as orphans when they're actually heavily used.
In a large Go codebase, graphify reported 12 files as orphaned with zero edges. Manual grep revealed that methods in those files have 34+ callers — they're some of the most-used code in the project.
Root Cause
1. Method receiver type nodes are file-scoped, not package-scoped
extract_go()at line ~1238:If a type is defined in
foo.gobut has methods inbar.goandbaz.go, each file creates its own type node with a different ID. These are separate disconnected nodes in the graph, not one canonical type.2. Call resolution is single-file only
label_to_nid(line ~1290) is built from nodes extracted from the current file only. When one file calls a method defined in another file within the same package, the call resolver can't find it because it only searches the current file's label map.This means all cross-file method calls within a Go package are invisible to the graph.
Impact
Suggested Fix
For type node IDs
Use the package path + type name instead of file stem + type name:
Where
package_pathis derived from the directory. All methods on a type across all files in the same package would share one node.For cross-file call resolution
Run extraction in two passes:
label_to_nidmap for all files sharing a Go package, then resolve calls against the full mapThis mirrors how Go itself resolves identifiers — package-scoped, not file-scoped.
Environment