Skip to content

audit(xaml): XAML100 — extend resource-hoist to Styles/templates (deep signature)#128

Merged
PhysShell merged 2 commits into
mainfrom
claude/oun-net-html-analyzer-drff2t
Jun 26, 2026
Merged

audit(xaml): XAML100 — extend resource-hoist to Styles/templates (deep signature)#128
PhysShell merged 2 commits into
mainfrom
claude/oun-net-html-analyzer-drff2t

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Follows #124 (XAML100 for Freezables). Extends the resource-hoist rule to Styles and templates, the higher-value half of the "52x52 collapse" — a duplicated Style/ControlTemplate is far heavier than a duplicated brush.

Why a deep signature

Styles/templates can't use the shallow type+attrs signature: two unrelated Styles both have Setter children, so a shallow sig would collapse them and mis-flag distinct styles as duplicates. So this adds _deep_resource_sig — a recursive full-subtree signature (tag + non-x:Key attrs + ordered child signatures). A Style/ControlTemplate/DataTemplate collapses only with a structurally identical twin (same setters / values / template tree), never a merely same-shaped one. Child order is significant — a conservative choice so only literal duplicates flag.

Freezable behavior is unchanged: a leaf brush's deep sig equals its old shallow sig.

Changes

  • xaml_check.py_deep_resource_sig; HOISTABLE_RESOURCE_TYPES = Freezables + Style/ControlTemplate/DataTemplate/HierarchicalDataTemplate/ItemsPanelTemplate; _rule_resource_hoist uses the deep sig for all of them.
  • selftest → 39 checks — an identical Style duplicated across control-local scopes flags; two Styles with different Setter values do not (proves deep equivalence). End-to-end confirmed identical ControlTemplates also flag.
  • docstring + design-note catalogue — Style/template no longer deferred.

Validation

Full audit selftest suite green (184 checks: normalize/score/report/xaml_check/xaml_facts/xaml_join/run_static/ingest), ruff check . clean.

🤖 Generated with Claude Code


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Expanded XAML resource hoisting detection to also flag duplicated Style/template resources when their full subtrees are structurally equivalent.
    • Enhanced equivalence matching with a deeper signature (including template text sensitivity) to avoid false positives.
    • Ensures true CLR Key values don’t trigger hoisting mismatches.
  • Documentation

    • Updated XAML100 guidance to reflect broader hoistable resources, including styles and templates.
  • Tests

    • Added self-coverage for style/template subtree matching and Key handling.

…p signature)

Follows #124 (XAML100 for Freezables). Styles/templates couldn't use the shallow
signature — two unrelated Styles both have `Setter` children, so a shallow
type-only sig would collapse them and mis-flag distinct styles as duplicates.

- _deep_resource_sig: a recursive full-subtree signature (tag + non-x:Key attrs +
  ordered child signatures), so a Style/ControlTemplate/DataTemplate only collapses
  with a structurally identical twin (same setters/values/template), never a
  merely same-shaped one. Child order is significant (conservative: only literal
  duplicates flag).
- HOISTABLE_RESOURCE_TYPES = Freezables + Style/ControlTemplate/DataTemplate/
  HierarchicalDataTemplate/ItemsPanelTemplate; _rule_resource_hoist now uses the
  deep sig for all of them (Freezable behavior unchanged — a leaf brush's deep sig
  equals its old shallow sig).
- selftest grows to 39: an identical Style duplicated across control-local scopes
  flags; two Styles with different Setter values do NOT (proves deep equivalence).
- docstring + design-note catalogue updated (Style/template no longer deferred).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015zoG4YNCUf7RA5r8GAXMmb
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1111d313-a919-4af9-82b1-43a6e9bf6780

📥 Commits

Reviewing files that changed from the base of the PR and between 371116b and 57ed39f.

📒 Files selected for processing (1)
  • audit/static/tools/xaml_check.py

📝 Walkthrough

Walkthrough

XAML100 now treats structurally identical heavy keyed resources, including styles and templates, as hoist candidates. The analyzer text, matching logic, parsing support, and selftests were updated to match that broader scope.

Changes

XAML100 resource hoisting expansion

Layer / File(s) Summary
Scope and candidate types
audit/static/tools/xaml_check.py, docs/notes/xaml-analyzer-design.md
XAML100 wording now covers hoistable heavy resources beyond Freezables, and HOISTABLE_RESOURCE_TYPES adds style/template types.
Deep resource matching
audit/static/tools/xaml_check.py
parse_xaml now captures character data, and _rule_resource_hoist uses _deep_resource_sig to compare resource subtrees by tag, attributes, text, and child order for XAML100.
Style hoist selftest
audit/static/tools/xaml_check.py
The selftest adds style and template cases across local scopes and checks matching, non-matching, and key-sensitive comparisons against XAML100.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PhysShell/Own.NET#114: Introduces the XAML100 hoisting implementation that this PR extends with deep structural matching and broader resource types.
  • PhysShell/Own.NET#124: Touches the same XAML100 ResourceShouldBeHoisted logic and related signature strategy in audit/static/tools/xaml_check.py.

Poem

I hop where styles and templates grow,
With setter twins in neat row by row.
A bunny sniffs the XAML air,
And says, “If matched, then hoist with care!” 🐇

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: extending XAML100 resource-hoisting to styles/templates with deep signature matching.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/oun-net-html-analyzer-drff2t

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 371116b823

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread audit/static/tools/xaml_check.py
Comment thread audit/static/tools/xaml_check.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@audit/static/tools/xaml_check.py`:
- Around line 407-418: The deep resource signature currently ignores node text,
so structurally identical elements with different character data can still
collide. Update the parser/tree model used by _deep_resource_sig so Node retains
relevant text content, then incorporate that text into the signature alongside
tag, attributes, and children. Make sure the change is applied consistently
where Node is built and where _deep_resource_sig walks the tree.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 75841c5a-7bac-4ba1-825a-3f388057812b

📥 Commits

Reviewing files that changed from the base of the PR and between e2ad2dd and 371116b.

📒 Files selected for processing (2)
  • audit/static/tools/xaml_check.py
  • docs/notes/xaml-analyzer-design.md

Comment thread audit/static/tools/xaml_check.py Outdated
…clusion (review)

Two false-positive fixes from the Codex/CodeRabbit review on PR #128's deep
template signature:

- Capture character data. Node never stored text, so the deep signature treated
  <DataTemplate><TextBlock>OK</> and ...Cancel... as identical and XAML100 would
  flag text-different templates as duplicates. Added Node.text + an expat
  CharacterDataHandler (accumulates across split runs), and the trimmed text is now
  part of _deep_resource_sig.
- Make the x:Key exclusion prefix-aware. The signature dropped every attribute whose
  local name is "Key", not just the resource directive x:Key — so a descendant CLR
  `KeyBinding Key="Enter"` vs "Escape" was erased, collapsing non-identical
  templates. _is_xkey now excludes only a prefixed `x:Key`; a bare CLR `Key` stays
  in the signature. Attribute names are kept raw (prefix included) for fidelity.

Selftest grows to 42: templates differing only in text are not duplicates (identical
text still collapses); a descendant KeyBinding Key keeps templates distinct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015zoG4YNCUf7RA5r8GAXMmb
@PhysShell
PhysShell merged commit 865d518 into main Jun 26, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants