Theme / v0.9.73

Graphify

Codebase 知識圖譜

實戰範例

實戰範例 011:用 v0.9.73 追蹤 enum 成員與跨檔呼叫

v0.9.73 新功能實戰:用 graphify 追蹤 Rust/Zig/C++/Scala 的 enum 成員、Java 繼承方法解析,以及 JSX 元件的 render 關係。

這個範例要解決的問題

你的團隊維護一個多語言 monorepo:Rust 後端、TypeScript 前端、一些 C++ 工具。你想回答:「這個 enum 的所有成員分別在哪裡被使用?」

在 v0.9.73 之前,Rust、Zig、C++ 與 Scala 3 尚未有這版新增的 enum 成員節點與 case_of 關係;其他語言已有 enum 成員擷取。新增節點有助於定位宣告,但不能代替編譯器檢查 match 是否完整。


第一步:確認圖譜已重建

graphify update .

第二步:追蹤 Rust enum 成員

假設你有:

enum PaymentState {
    Pending,
    Authorized,
    Captured,
    Refunded,
}

v0.9.73 之後,每個 variant 都是節點,PaymentState 以 case_of 邊連到成員。查詢:

graphify query "PaymentState variants"
  PaymentState (enum)
    ├── case_of → Pending
    ├── case_of → Authorized
    ├── case_of → Captured
    └── case_of → Refunded

上圖是結構示意,並非 graphify query 的實際輸出格式。同樣的擷取也適用於 Zig enum members、C++ enum/enum class enumerators(含巢狀 enum)與 Scala 3 enum cases(含其方法)。


第三步:定位 variant,再核對原始碼

有了成員節點,可以用關鍵字取得周邊圖譜資訊:

graphify query "PaymentState Pending"

query 會從符合關鍵字的節點遍歷,受深度與 token 預算限制;它不是完整的 caller 清單。沒有查到使用位置,不能證明 variant 未被使用或 match 漏了分支。請回到原始碼核對;Rust 的 match 窮盡性應由編譯器確認。

隨堂測驗

查詢 enum variant 沒有找到使用位置,能得出什麼結論?

💡 想先看個提示?

查詢範圍與實際程式行為,是兩種不同的證據。


第四步:Java 繼承方法解析

v0.9.73 修正了 Java 呼叫繼承方法與 super.method() 的解析——現在會走到宣告祖先(走 inherits 鏈,最近者勝):

graphify query "OrderService.process"
  OrderService.process()
    ↓ calls
      BaseService.validate()   ← 解析到宣告它的祖先,而非懸空

上圖為解析關係示意,並非 CLI 的逐字輸出。未知或外部的祖先會 fail closed(保持 unresolved),而不是猜一個同名方法。


第五步:JSX 元件的 render 關係

v0.9.70 起,JSX 元件使用會產生 calls 邊:

<MyButton onClick={handleClick} />
<_Row data={items} />
<div>...</div>          {/* 小寫 DOM 標籤:跳過 */}
<Nav.Item />            {/* 成員標籤:跳過 */}
graphify query "MyButton callers"

可取得 MyButton 周邊已擷取的 render 關係;這是受查詢範圍限制的圖譜資訊,不保證列出所有使用位置。


第六步:安全修復的驗證(v0.9.70)

如果你的 repo 含 Fortran(大寫 .F/.F90),v0.9.70 修復了一個嚴重問題:不可信的原始碼曾能藉 #include "/etc/passwd" 把主機檔案讀進 graph.json。


常見誤區

誤區 事實
「升級就有新節點」 需重新萃取,節點與邊是萃取時寫入
「enum 成員本來就是節點」 v0.9.73 才擴及 Rust/Zig/C++/Scala
「所有 JSX 標籤都連邊」 小寫 DOM 與成員標籤保守跳過
「安全修復會清掉舊圖的洩漏」 需重建圖譜才會清除

動手練習

  1. 找一個 Rust 或 C++ enum,用 graphify query 定位宣告與已擷取的成員
  2. 核對 variant 的原始碼使用位置;Rust 專案可執行 cargo check 確認 match 是否滿足窮盡性要求
  3. 找一個 JSX 元件,查看已擷取的 render 關係並與原始碼比對

延伸閱讀