Skip to content

audit(xaml): add XAML105 MergedDictionaryKeyShadowing (in-file)#130

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

audit(xaml): add XAML105 MergedDictionaryKeyShadowing (in-file)#130
PhysShell merged 3 commits into
mainfrom
claude/oun-net-html-analyzer-drff2t

Conversation

@PhysShell

@PhysShell PhysShell commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Completes the merged-dictionary story — XAML104 catches a duplicate include, XAML105 catches a duplicate key.

XAML105 MergedDictionaryKeyShadowing

The same x:Key defined in ≥2 inline merged dictionaries, or in the primary dictionary AND an inline merged one. The effective value then depends on merge order (WPF: last merged wins; a primary key beats merged ones) — a silent order-dependence that breaks when includes are reordered.

resource key 'accent' is defined in 2 merged/primary scopes
[merged #1 (line 4), merged #2 (line 7)]; the effective value depends on merge
order (last merged wins, primary beats merged) [resource: merged dictionary]
  • In-file only. Dictionaries pulled in by Source="..." reference external files this single-file pass can't resolve, so their keys aren't compared — the cross-file variant is a documented later slice (it needs the runner to resolve Source paths against the scanned file set).
  • FP-safe — only literal same-key collisions flag; a lone key (the normal case) never does, and external Source= dicts are explicitly not compared.

Changes

  • xaml_check.py_rule_merged_dict_shadowing, registered in RULES; docstring + deferred-note updated.
  • taxonomyXAML105 → category 9 (merged-dictionary-shadowing).
  • selftest → 47 checks — two inline merged dicts colliding flags; a primary+merged collision flags; distinct keys do not; external Source= dicts are not compared.
  • README + design-note catalogue updated.

Validation

Full audit selftest suite green (192 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

  • New Features

    • Added a new XAML analyzer warning (XAML105) to detect order-dependent x:Key shadowing across the primary resources and inline merged dictionaries.
    • Reports collisions with enough context to pinpoint where the competing keys appear, while avoiding in-scope duplicate-key noise.
  • Documentation

    • Updated the rule catalogue and design notes to clarify the rule’s scope to in-file inline merged dictionaries (with cross-file Source handling deferred).
  • Tests

    • Extended analyzer self-tests to cover XAML105 scenarios and non-finding cases.

Completes the merged-dictionary story (XAML104 = duplicate include) with the key
shadowing case: the same x:Key defined in >=2 inline merged dictionaries, or in the
primary dictionary AND an inline merged one. The effective value then depends on
merge order (WPF: last merged wins, a primary key beats merged ones) — a silent
order-dependence that breaks when includes are reordered.

In-file only: dictionaries pulled in by Source="..." reference external files this
single-file pass can't resolve, so their keys aren't compared (cross-file variant
documented as a later slice). FP-safe — only literal same-key collisions flag; a
lone key (the normal case) never does.

- xaml_check.py: _rule_merged_dict_shadowing, registered in RULES; docstring updated.
- taxonomy: XAML105 -> category 9 (merged-dictionary-shadowing).
- selftest grows to 47: two inline merged dicts colliding flags; primary+merged
  collision flags; distinct keys don't; external Source= dicts are not compared.
- README + design-note catalogue updated.

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

@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: b351ea4066

ℹ️ 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
A ResourceDictionary that declares the same x:Key twice directly (or twice
inside one inline merged dictionary) is a duplicate-key error within a single
scope — runtime-invalid, but a different problem from XAML105's order-dependent
merge shadowing. The old check fired on any key with 2+ occurrences, so two
primary entries sharing a key were mislabeled as [primary, primary] shadowing.

Collisions now require the key to span 2+ DISTINCT scopes (primary vs merged,
or two different merged dicts). Added a selftest: two same-key primary entries
plus a non-colliding merged dict must not emit XAML105.

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: 2e26ed53-961f-4bfb-b4b2-f2fba67f0217

📥 Commits

Reviewing files that changed from the base of the PR and between 044dc0f and c02b1eb.

📒 Files selected for processing (1)
  • audit/static/tools/xaml_check.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • audit/static/tools/xaml_check.py

📝 Walkthrough

Walkthrough

Adds XAML105 for merged-dictionary key shadowing, updates taxonomy and documentation to describe the inline/in-file scope, and extends the analyzer with rule logic, registration, and selftests.

Changes

XAML105 merged-dictionary shadowing

Layer / File(s) Summary
Rule scope and taxonomy
audit/static/tools/xaml_check.py, audit/static/taxonomy/categories.yml, docs/notes/xaml-analyzer-design.md, audit/README.md
Updates the XAML105 catalogue text, taxonomy mapping, and docs to describe inline/in-file merged-dictionary key shadowing and deferred Source= handling.
Shadowing detection
audit/static/tools/xaml_check.py
Adds _rule_merged_dict_shadowing, which collects x:Key occurrences from the primary dictionary and inline merged dictionaries and emits XAML105 for keys seen in multiple scopes.
Registration and selftests
audit/static/tools/xaml_check.py
Inserts the new rule into RULES and adds selftests for inline shadowing, primary-plus-inline shadowing, distinct keys, Source= dictionaries, and same-scope duplicate keys.

Sequence Diagram(s)

sequenceDiagram
  participant xaml_check.py
  participant RULES
  participant _rule_merged_dict_shadowing
  participant XAML105
  xaml_check.py->>RULES: iterate phase-1 rules
  RULES->>_rule_merged_dict_shadowing: run analyzer
  _rule_merged_dict_shadowing->>_rule_merged_dict_shadowing: scan primary and inline merged dictionaries
  _rule_merged_dict_shadowing->>XAML105: emit shadowing finding
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PhysShell/Own.NET#114: Introduces the XAML Phase-1 analyzer foundation that this PR extends with XAML105, taxonomy, and docs updates.

Poem

(\/)
( •
•) I hopped through merged dictionaries,
/ >🥕 and sniffed each shadowed key.
XAML105 squeaked, "No more collisions!"
The moonlit resources danced with me.

🚥 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 summarizes the main change: adding XAML105 MergedDictionaryKeyShadowing with the in-file scope.
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.

@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 432-443: The XAML105 finding in xaml_check.py still formats raw
occurrences, so same-scope duplicates can leak into the reported scope count and
location list. Update the XamlFinding construction in the XAML105 path to
deduplicate occurrences by scope before building the message, while keeping the
existing distinct-scope gate logic in place. Use the keymap/occ processing
around the XAML105 emission so the count and “where” string only reflect unique
scopes, not repeated entries from the same scope.
🪄 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: 07d3ea69-3a48-478a-86a2-269fbdc4d977

📥 Commits

Reviewing files that changed from the base of the PR and between 865d518 and 044dc0f.

📒 Files selected for processing (4)
  • audit/README.md
  • audit/static/taxonomy/categories.yml
  • audit/static/tools/xaml_check.py
  • docs/notes/xaml-analyzer-design.md

Comment thread audit/static/tools/xaml_check.py
The distinct-scope gate was correct, but the emitted finding still formatted
raw occurrences: a key appearing twice in the primary dict AND once in a merged
dict reported "3 merged/primary scopes" and listed "primary" twice. Collapse
occurrences to the first line per scope before building the message, so the
count and the "where" list reflect distinct scopes only. Added a selftest
(dup primary + merged → "2 scopes", "primary" listed once).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015zoG4YNCUf7RA5r8GAXMmb
@PhysShell
PhysShell merged commit 78c27dd 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