概述
Graphify v0.9.101 於 2026-11-02 發布。官方 release notes 的定位是:
“Resolution-accuracy and cache-correctness release across C++, Rust, Python, Go, the build write guard, and incremental rebuilds.”
本版沒有新命令或新介面,重點是把「呼叫解析」與「快取/重建」兩類既有行為修正:跨檔解析綁到正確的目標、折疊(fold)不再吃掉合法證據、快取鍵不再因大小寫碰撞。本課逐項對應 release notes 原文;上游沒有細節的行為,這裡也不推測。
C++:呼叫綁定看 receiver,定義找唯一 owner
成員呼叫依 receiver 型別解析
Release notes 原文:「A member call x.m() binds by the receiver’s type, now typed from function parameters and class fields and not only locals (void render(Base* b){ b->draw(); } resolves to Base::draw); an untyped or ambiguous receiver keeps its in-file binding (#3215, #4946).」
也就是說,成員呼叫(member call)x.m() 依 receiver x 的型別決定綁定目標,而這個型別的推導來源從區域變數(locals)擴及函式參數與 class fields。例子中 render(Base* b) 內的 b->draw() 會解析到 Base::draw。如果 receiver 未定型或無法唯一判定,則保守地維持 in-file binding——不猜。
out-of-line 定義附加到唯一 owner
Release notes 原文:「An out-of-line or split-header definition attaches to the unique owner whose class file is in its include set, instead of cross-binding to an unrelated same-named function; ambiguous owners fail closed (#4916, #4920).」
Out-of-line 或 split-header 的成員定義,會附加到 include set 內含其 class 檔的那個唯一 owner,不再跨檔綁到無關的同名函式;當 owners 有歧義時選擇 fail closed(拒絕判定),而非隨機挑一個。
區域可呼叫值不污染全域解析
Release notes 原文:「A local callable value (a lambda or std::function) is kept out of global call resolution by byte-range binding lifetimes, so it no longer mints a spurious INFERRED call to a same-named global; a later legitimate global call survives (#4917, #4921).」
區域可呼叫值(lambda、std::function)以 byte-range binding 生命週期隔離,不會再被當成對同名全域函式的呼叫而鑄造假的 INFERRED call edge;同一處之後真正對全域函式的合法呼叫仍會被保留。
型別別名依精確拼寫綁定
Release notes 原文:「A type-alias reference (using Foo = Bar; then Foo x;) binds by exact spelling and a salted alias keeps its own contains edge (#4951).」
using Foo = Bar; 之後的 Foo x; 依精確拼寫(exact spelling)綁定,salted alias 保有自己獨立的 contains edge。
Rust:模組限定呼叫與巨集引數內的呼叫
模組限定呼叫不跨出 crate
Release notes 原文:「A module-qualified call (crate::b::helper(), super::m::f()) resolves through qualifier-verified cross-file resolution, staying inside the caller’s crate (#2135, #4944).」
帶模組限定詞(qualifier)的呼叫如 crate::b::helper()、super::m::f(),現在經 qualifier 驗證後可跨檔解析,且結果不跨出呼叫者所在的 crate。
巨集引數內的呼叫會被連結
Release notes 原文:「A call written inside an expression macro’s arguments (println!("{}", f()), vec![g()]) is linked, gated to an allowlist so macro_rules! bodies and custom DSLs are left alone (#4945).」
寫在 expression macro 引數裡的呼叫,例如 println!("{}", f()) 或 vec![g()],會被連結(linked)。範圍以 allowlist 限制:macro_rules! 本體與自訂 DSL(custom DSLs)不在處理範圍內。
Python 與 Go:裸呼叫、namespace packages、method value
Release notes 原文列出四項:
- 方法內裸呼叫(#4933):「A bare call inside a method no longer self-binds to a same-named method; it resolves to the imported or module-level function it names.」方法內的裸呼叫不再自綁到同名的 method,而是解析到它指名的 imported 或 module-level 函式。
- PEP 420 namespace packages(#4929):「Imports resolve across PEP 420 namespace packages split over multiple
src/roots.」imports 可跨多個src/根目錄拆分的 PEP 420 namespace packages 解析。 - Go method value(#1566、#4931):「A Go method value reached through a receiver field is linked as an
indirect_call.」經 receiver field 取得的 Go method value 會以indirect_call連結。 - Go var 初始化式(#2360、#4932):「A Go package-level
varinitialiser references the types it names.」package-levelvar的初始化式會參照它指名的型別。
Build/cache/rebuild/watch:折疊與快取的正確性
Write guard 與節點折疊
Release notes 原文:「The write guard no longer refuses a healthy graph when entity dedup folds a saved node into a surviving twin; a genuine loss is still refused (#4940, #4952).」
Entity dedup 把一個已保存節點折疊進倖存的孿生節點時,write guard 不再誤判為資料遺失而拒絕寫入健康 graph;但真正的資料遺失仍會被拒絕。
Release notes 原文:「Independently sourced semantic file evidence survives a fold into an AST file-self node; ordinary INFERRED mention ghosts still fold so graphs do not accumulate duplicates (#4896, #4927).」
獨立來源(independently sourced)的語意檔案證據,在折疊進 AST file-self 節點後仍會倖存;一般 INFERRED 的提及幽靈(mention ghosts)仍照舊折疊,以免 graph 累積重複節點。
Release notes 原文:「The file-stem alias index only rebinds an edge when the edge’s file and the alias target share a language family (#4949).」
File-stem alias index 只在 edge 所屬檔案與 alias 目標同屬一個語言族(language family)時才重綁(rebind)那條 edge。
快取鍵大小寫與長路徑
Release notes 原文:「Cache keys keep their written case so README.md and readme.md no longer collide, and hashed/word-count files are opened through os_long_path (#4925, #4937).」
快取鍵(cache key)保留檔名的書寫大小寫,README.md 與 readme.md 不再碰撞而互相污染;hashed 與 word-count 檔案改以 os_long_path 開啟。
重建與 watch 行為
- code-only 一致性(#4923、#4939):「A
--code-onlygraph stays code-only across hook,updateand watch rebuilds.」--code-onlygraph 在 hook、update與 watch 重建中都維持 code-only。 - 鎖定等待(#4924、#4926):「A rebuild no longer waits forever when
msvcrt.lockingis unsupported.」在不支援msvcrt.locking的環境,重建不再無限等待。 - 排除 worktree(#4919):「A full reconcile evicts source records for an excluded linked git worktree.」完整 reconcile 會把被排除的 linked git worktree 之 source records 逐出。
- AST-only 更新(#4950):「AST-only updates preserve cross-file semantic evidence whose node id collides with a code definition.」AST-only 更新會保留那些 node id 與 code 定義碰撞的跨檔語意證據。
- sliced file 快取(#4943、#4947):「A sliced file is cached only once every slice has succeeded and is assembled in chunk order.」sliced file 只在每個 slice 都成功後才會快取,並按 chunk 順序組裝。
AST cache schema bump 至 36
Release notes 原文:「The AST cache schema is bumped to 36; warm caches re-run the affected extractions.」
AST cache schema 版號升至 36;已有 warm cache 的使用者,受影響的抽取(extractions)會自動重跑。這是升級後首次重建可能變慢的正常原因——release notes 只說會重跑受影響的抽取,並未提供重跑範圍或耗時的量化數據,不宜自行推估。
v0.9.101 中,C++ 成員呼叫 `b->draw()`(`b` 為函式參數 `Base* b`)會如何解析?
💡 想先看個提示?
重點是 receiver 型別的推導來源變廣,且歧義時寧可不猜。
動手檢查清單
升級 v0.9.101:動手檢查清單
逐項勾選,確認你已完成升級必要的步驟(進度會保存在此瀏覽器)