[pull] v8 from safishamsi:v8#98
Merged
Merged
Conversation
#1561) A hyperedge's member list is canonically keyed `nodes`, but producers (LLM/subagent drift, externally-supplied graph.json) sometimes emit `members` or `node_ids` — graphify only read `nodes`, so those hyperedges silently lost their members, and semantic_cleanup's prune dropped them entirely. Normalize the member key to `nodes` at one ingest chokepoint in build_from_json (and in semantic_cleanup, which runs pre-build), deduping and warning, so every downstream consumer sees the canonical key. Mirrors the existing from/to edge-endpoint aliasing. Reported by @askalot-io. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ph (#1553) The cross-file call resolver bailed (#543/#1219 god-node guard) whenever a bare callee name had 2+ definitions without unique import evidence — so a single same-named test mock (or any same-named symbol) dropped the real `calls` edge, erasing the call graph wherever a mock existed (the reporter saw a 76-stub Pester suite wipe everything). Replace the blunt bail with a smarter guard: when a name is ambiguous and import evidence doesn't resolve it, apply tie-breakers — non-test preference (a shared, segment-aware _is_test_path classifier) then path proximity — and emit an INFERRED edge ONLY if exactly one candidate survives, else keep bailing. A real def + a test mock resolves to the real def; two genuine non-test defs still bail (god-node guard intact, no fan-out). Wired into both the extract.py pass and the symbol_resolution.py copy via the shared classifier. Reported by @Schweinehund. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… routing (#1556, #1547) A class declared in a header (Foo.h/@interface) and defined in its impl (Foo.cpp/Foo.m/@implementation) fragmented into two nodes: _file_stem drops the extension so Foo.h and Foo.cpp share a node id, which _disambiguate_colliding_node_ids then split apart by path — and the two "defs" tripped every resolver's single-definition god-node guard, cascading into missing .h<->.m/.cpp linkage and cross-file/cross-language edges. - Routing: a `.h` using `#import` now routes to extract_objc (#1556 bridging headers — extract_c drops `#import` as a preproc_call), and a `.h` with C++-only signals (class/namespace/template/::/access-specifiers) routes to extract_cpp (#1547 — the C grammar has no class_specifier, so a C++ header previously yielded a junk node and lost every method). ObjC sniff keeps priority; a plain C header still routes to extract_c. - Merge: a new _merge_decl_def_classes post-pass collapses the header/impl id-collision onto the header (declaration) variant, modeled on _merge_swift_extensions, gated so it fires ONLY for a clean sibling header/impl pair (same dir, same base stem, exactly one header) — two same-named classes in different directories have different stems and never collide, so they are never merged (god-node guard verified). C++ method definitions retain their `Foo::` qualifier so a `Foo::bar` def keys onto the header declaration (one method node, not two); free functions keep their bare-name ids. Result: one canonical class node per .h/.m or .h/.cpp pair with methods unified, which unblocks the existing member-call resolvers (verified Swift->ObjC calls and Swift `extension` folding now resolve). Strict improvement over v8 (which produced junk/fragmented nodes here, verified). Still open as follow-ups: cross-file C++ #include edge resolution and a C++/ObjC cross-file member-call resolver (a pre-existing gap, not a regression). Reported by @JabberYQ (#1556) and @c0dezer019 (#1547). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
, #1556) Connects paired classes across files: Main.cpp's `Foo f; f.bar()` now resolves to Foo::bar, and ObjC `Foo *f = [[Foo alloc] init]; [f doThing]` to Foo's doThing — the "connect with other classes" goal of #1547/#1556. Design grounded in prior-art research (ctags qualified-name matching, Doxygen's name-keyed false-edge failure modes, PAIGE's receiver-type approach, Clang USR): resolve by RECEIVER TYPE, never bare name, and skip when the type can't be inferred rather than guess (a false call edge / god-node is worse than a missing one). Mirrors the existing Swift/Python/Ruby/TS member-call resolvers. - C++ extractor now captures the member-call receiver (field_expression / qualified_identifier / pointer access) and builds a per-file type table from local declarations (`Foo f;`, `Foo* f;`, `Foo *f = ...;`); emits raw_calls. - ObjC extractor emits raw_calls for message sends with the receiver + selector and a type table from `Foo *f = ...;` locals (existing in-file selector / alloc-init / dot-syntax / @selector matching preserved). - New _resolve_cpp_member_calls / _resolve_objc_member_calls, registered for their suffixes. Receiver tiers: `Foo::bar()` / capitalized ObjC receiver and this/self/super (enclosing class) -> EXTRACTED; local-var-typed -> INFERRED. Single-definition god-node guard (skip unless exactly one type def matches); the just-shipped decl/def class merge makes a paired class one def so the guard resolves it. Verified: a.run() -> A::run only (not a same-named B::run); an uninferable receiver with run() in two classes emits zero edges (no fan-out); ObjC [f doThing] -> Foo only. - build.py: the cross-language INFERRED-call prune treated .h/.cpp/.m as different families and dropped header/impl interop calls; unified the C family (.c .h .cc .cpp .hpp .cxx .hh .hxx .cu .cuh .metal .m .mm) so a .cpp/.m call to a .h-declared method survives. Still open (tracked on #1547/#1556): the file-level `#include` edge can stay uncanonicalized when the project root isn't symlink-resolved (the extract() id-remap `continue`s on a /var-vs-/private/var mismatch) — the class connection above is robust to it; include-reachability candidate narrowing and ObjC dynamic-dispatch/id-typed receivers also deferred (expected low ObjC recall, per the research). Reported by @c0dezer019 (#1547) and @JabberYQ (#1556). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extends the C# type-reference resolver (#1466) to be namespace-aware, advancing the #1318 shadow-node umbrella for C#: - The namespace is folded into the C# node id (_make_id(stem, namespace, name)), so two same-named types in different namespaces in one file no longer collapse — replacing #1466's detect-and-skip workaround for multi-namespace files. - Lexical per-block using-scope: a `using` applies only where it is in scope (file-level, or the enclosing namespace block via a scope chain), so sibling namespace blocks no longer share each other's usings. - Qualified references (`Namespace.Type`) resolve via in-scope aliases (`using Q = X.Y`) then exact known namespaces; generics are stripped. Preserves (and tightens) the refuse-rather-than-guess discipline: a bare reference resolves only when exactly one in-scope namespace provides the type; an ambiguous reference (e.g. `using A; using B;` both defining `Widget`) resolves to nothing rather than fanning out. Verified: `using A` -> A.Widget only; ambiguous -> no edge; qualified `B.Widget` -> B.Widget regardless of usings; sibling-block using-scope isolated; no dangling edges or fan-out. Reconciled onto current v8 (the PR predated the C++/ObjC member-call resolvers); full suite green, the C++/ObjC resolution coexists. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cross-file member-call resolution for C++/ObjC (#1547/#1556) and namespace-aware C# type resolution (#1562), the work-memory overlay (#1441), test-mock call-graph fix (#1553), hyperedge member-key aliases (#1561), plus the TS/JS/ObjC resolution fixes (#1316/#1544/#1552/#1475). See CHANGELOG. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )