Skip to content

Commit 905e0a7

Browse files
MikeKatsoulakisclaude
authored andcommitted
feat(extract): link XAML views to ViewModels and extract binding references (Graphify-Labs#1473)
Builds on the initial XAML support (Graphify-Labs#1460). Resolves a view to its ViewModel from an explicit <Window.DataContext><vm:MainViewModel/>, a design-time d:DataContext="{d:DesignInstance Type=...}", the View->ViewModel naming convention, or Prism ViewModelLocator.AutoWireViewModel="True". Resolution is always against an actually-extracted C# class node, so a name matching no class (or an ambiguous 2+) emits no edge -- explicit DataContext is EXTRACTED, convention/Prism are INFERRED. Also extracts binding paths ({Binding User.Name}, Path=Order.Total), commands (Command="{Binding SaveCommand}"), converters, and CommunityToolkit [ObservableProperty]/[RelayCommand] generated members. The Graphify-Labs#1460 event-handler hardening is preserved unchanged: events still resolve only to methods with a .NET (object sender, ...EventArgs e) signature, and the free-form-attribute denylist still prevents values like Content="Save" from fabricating event edges (both regression tests still pass). ViewModel discovery is bounded to the active extraction root. Ported from PR Graphify-Labs#1473 by @MikeKatsoulakis (clean 3-way merge onto current v8). Maintainer fix on top: the CommunityToolkit member reader now reads the code-behind with errors="replace", so a non-UTF8 ViewModel .cs can't raise UnicodeDecodeError and abort extract_xaml (matches every other reader in the module). Added a regression test for that case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 349465b commit 905e0a7

15 files changed

Lines changed: 699 additions & 13 deletions

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu
44

55
## Unreleased
66

7+
- Feat: link WPF/XAML views to their ViewModels and extract richer binding references (#1473, thanks @MikeKatsoulakis). Builds on the initial XAML support (#1460). Resolves a view to its ViewModel from an explicit `<Window.DataContext><vm:MainViewModel/>`, a design-time `d:DataContext="{d:DesignInstance Type=…}"`, the `View`→`ViewModel` naming convention, or Prism `ViewModelLocator.AutoWireViewModel="True"` — always against an actually-extracted C# class, so a name with no matching class (or an ambiguous one) emits no edge (explicit DataContext is EXTRACTED, conventions are INFERRED). Also extracts binding paths (`{Binding User.Name}`, `Path=Order.Total`), commands (`Command="{Binding SaveCommand}"`), converters, and CommunityToolkit `[ObservableProperty]`/`[RelayCommand]` generated members. The event-handler resolution stays gated on the .NET handler signature (no spurious event edges), and ViewModel discovery is bounded to the extraction root.
78
- Fix: `.vue` Single File Components now extract their `<script>` with the right grammar (#1468, thanks @papinto). `.vue` was dispatched to `extract_js`, which selects a tree-sitter grammar by suffix; `.vue` is neither `.ts` nor `.tsx`, so the whole SFC — `<template>` markup, `<script>`, and `<style>` — was parsed as JavaScript, producing a top-level ERROR node and recovering no imports, symbols, or type references. A dedicated `extract_vue` now masks everything outside `<script>` (replacing it with spaces so line numbers stay accurate) and parses just the script with the grammar named by `lang` (`ts` default, `tsx`/`js`/`jsx` honored). The open-tag scan tolerates `>` inside quoted attributes, so Vue 3.3+ generic components (`generic="T extends Record<string, unknown>"`) parse correctly.
89
- Fix: `graphify reflect --if-stale` now also checks the `.graphify_analysis.json` and `.graphify_labels.json` sidecars (and any custom `--analysis`/`--labels` paths) when deciding whether `LESSONS.md` is up to date (#1470, thanks @oleksii-tumanov). It previously only stat'd the memory docs and `graph.json`, so lessons could stay stale after community analysis or labels changed without the graph changing. A missing sidecar is treated as not-an-input, so no-cluster builds are unaffected.
910
- Fix: the `Read|Glob` PreToolUse hook (the "run graphify first" nudge installed for Claude Code and CodeBuddy) now matches the file's real trailing extension instead of substring-scanning the path (#1463, thanks @marketechniks). The old check asked `any(ext in path)`, which had two opposite failures: `.json` files (`package.json`, `tsconfig.json`) spuriously fired because `.js` is a substring of `.json`, and `.astro`/`.vue`/`.svelte` never fired because they weren't in the set — so on Astro/Vue/Svelte projects, where those are the primary source type, reads and globs never surfaced the graph. The hook now compares the segment after the last `/` then after the last `.` against the extension set (with `.astro`/`.vue`/`.svelte` added), so `package.json` stays silent, `data.geojson` stays silent, `**/*.astro` fires, and an extension sitting on a directory component (`my.ts/file`) correctly doesn't. The `graphify-out/` suppression and fail-open behavior are unchanged.

0 commit comments

Comments
 (0)