fix(canon): anchor prop-type errors at the attribute name#3205
Conversation
vue-tsc anchors a component prop-type error at the attribute name while the check identifier's sub-span pointed at the authored value, so vize reported the same TS2322 two columns away on both the batch and the language-server paths. The check identifier now carries an attribute-name sub-span — computed after the v-bind:/: prefix so names like bind cannot anchor inside v-bind: and modifiers like .camel cannot steal the match — and the initializer carries its own exact-expression sub-span so errors inside the value still land on the authored bytes. On the reference repro both engines now report TS2322 at byte-identical positions, and the four real-project snapshots re-baseline with every removed line verified as a same-message merge onto the shared attribute-name position.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📜 Recent review details⏰ Context from checks skipped due to timeout. (8)
🧰 Additional context used📓 Path-based instructions (2)tests/tooling/**⚙️ CodeRabbit configuration file
Files:
crates/**⚙️ CodeRabbit configuration file
Files:
🔇 Additional comments (2)
📝 WalkthroughWalkthroughComponent prop checks now map synthetic identifiers to authored attribute-name ranges while preserving authored value-expression mappings. Tests cover static, bound, prefixed, modified, and multibyte props; related diagnostic expectations and workspace dependency overrides are updated. ChangesComponent prop diagnostic anchoring
Workspace dependency overrides
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
vize
@vizejs/fresco
@vizejs/musea-mcp-server
oxlint-plugin-vize
@vizejs/rspack-plugin
@vizejs/unplugin
@vizejs/vite-plugin
@vizejs/vite-plugin-musea
@vizejs/musea-nuxt
@vizejs/nuxt
@vizeui/core
commit: |
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
… past new advisories Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
There was a problem hiding this comment.
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 `@crates/vize_canon/src/virtual_ts/expressions/component_props_tests.rs`:
- Around line 240-280: The test
attribute_name_anchor_survives_prefixes_and_modifiers lacks coverage for
hyphenated attribute names. Add a kebab-case case such as :foo-bar="fooBar" and
assert that the generated prop-check mapping anchors to the foo-bar name span
(or its resolved normalized prop key), not the value range, using the existing
output and sub_spans validation pattern.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 788e6c73-4089-48de-ada5-4500a5142d39
⛔ Files ignored due to path filters (5)
crates/vize_canon/src/snapshots/vize_canon__batch__type_checker__tests__batch_type_checker_cross_file_vue_prop_error.snapis excluded by!**/*.snap,!crates/**/src/snapshots/**,!**/*.snaptests/snapshots/check/__snapshots__/elk-check.snapis excluded by!**/*.snap,!tests/snapshots/**,!**/*.snaptests/snapshots/check/__snapshots__/misskey-check.snapis excluded by!**/*.snap,!tests/snapshots/**,!**/*.snaptests/snapshots/check/__snapshots__/nuxt-ui-check.snapis excluded by!**/*.snap,!tests/snapshots/**,!**/*.snaptests/snapshots/check/__snapshots__/reka-ui-check.snapis excluded by!**/*.snap,!tests/snapshots/**,!**/*.snap
📒 Files selected for processing (2)
crates/vize_canon/src/virtual_ts/expressions/component_props.rscrates/vize_canon/src/virtual_ts/expressions/component_props_tests.rs
📜 Review details
⏰ Context from checks skipped due to timeout. (31)
- GitHub Check: Codesmith
- GitHub Check: Normalize titles and assignees
- GitHub Check: tool-benchmark
- GitHub Check: pr-benchmark
- GitHub Check: test-js-packages
- GitHub Check: build-js-packages
- GitHub Check: coverage
- GitHub Check: cargo-semver-checks (vize_atelier_core)
- GitHub Check: clippy-and-test
- GitHub Check: editor-extensions
- GitHub Check: cargo-semver-checks (vize_musea)
- GitHub Check: cargo-semver-checks (vize_armature)
- GitHub Check: cargo-semver-checks (vize_atelier_dom)
- GitHub Check: cargo-semver-checks (vize_carton)
- GitHub Check: cargo-semver-checks (vize_fresco)
- GitHub Check: cargo-semver-checks (vize_atelier_sfc)
- GitHub Check: vue-parity
- GitHub Check: cargo-semver-checks (vize_relief)
- GitHub Check: cargo-semver-checks (vize_atelier_vapor)
- GitHub Check: cargo-semver-checks (vize_atelier_ssr)
- GitHub Check: cargo-semver-checks (vize_croquis)
- GitHub Check: check-vize-apps
- GitHub Check: test-scripts
- GitHub Check: check-js
- GitHub Check: app-readiness
- GitHub Check: miri
- GitHub Check: criterion-ab
- GitHub Check: dialect-guard
- GitHub Check: Publish preview packages
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (1)
crates/**
⚙️ CodeRabbit configuration file
crates/**: Focus on parser/compiler correctness, source locations, UTF-8/UTF-16 offset handling, and panic-free LSP behavior. Flag changes that only work for small fixtures but break real Vue/Nuxt projects.
Files:
crates/vize_canon/src/virtual_ts/expressions/component_props.rscrates/vize_canon/src/virtual_ts/expressions/component_props_tests.rs
🔇 Additional comments (4)
crates/vize_canon/src/virtual_ts/expressions/component_props.rs (2)
217-248: Downstream of the name-matching gap above.The
name_src_range.or_else(|| value_src_range.clone())fallback at Line 232 is what silently converts the failure inprop_name_source_range(Lines 92-121) into a wrong-but-non-crashing anchor (value range instead of name range), with no signal that the "name anchoring" path was actually skipped.
92-121: 🎯 Functional Correctness
prop_name_source_rangealready handles kebab-case bindings;PassedProp.nameis stored as authored, so this branch still matches:foo-bar/v-bind:foo-bar.> Likely an incorrect or invalid review comment.crates/vize_canon/src/virtual_ts/expressions/component_props_tests.rs (2)
42-88: LGTM!
120-143: LGTM!
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
Tool BenchmarkMeasured: 2026-07-22T05:16:49.186Z
Fairness notes:
Commands: gh workflow run tool-benchmark.yml --ref <branch> -f file_count=3000 -f check_file_count=500 -f vite_file_count=1000 -f nuxt_file_count=250 -f large_blocks=300 -f runs=3 -f warmups=1 -f commit_results=true
node bench/generate.mjs 3000
node bench/compare-tools.mjs --input bench/__in__ --vize-bin target/release/vize --runs 3 --warmups 1 --check-file-count 500 --vite-file-count 1000 --nuxt-file-count 250 --large-blocks 300 --runner-label "blacksmith-32vcpu-ubuntu-2404" --out tool-benchmark-summary.md --json tool-benchmark-results.json --doc performance-blacksmith.mdVariant details and raw run timesSFC compile
Large SFC compile
Large SFC type check
Lint
Format
Type check
Vite build (end-to-end)
Nuxt SPA build (end-to-end)
|
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Repins the two remaining value-anchored expectations to the attribute name — the check-server dependency-patch column and the Misskey LSP shared-edit range, whose binding mode now asserts the :code attribute name like vue-tsc — and moves the prop source-range and generated-value helpers into expressions/prop_sources.rs to keep both files inside the new-source length budget.
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@crates/vize_canon/src/virtual_ts/expressions/component_props_tests.rs`:
- Around line 246-248: Extend the component props source-location fixtures
around the existing bind/sync/fooBar cases with non-ASCII template text before
an additional prop. Assert that the new prop’s source range uses the exact UTF-8
byte offsets, and apply the same coverage to the related fixture around the
other case. Preserve the existing ASCII assertions while ensuring UTF-8/UTF-16
offset handling does not regress.
In `@tests/tooling/lsp-typecheck-template.test.ts`:
- Line 224: Update the binding range setup around bindingStart to first capture
parent.indexOf(":count"), assert that the match exists with a focused
diagnostic, then pass the validated match offset plus ":".length to
offsetToPosition. Reuse that validated offset rather than performing the lookup
inline.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: 1c5a8c2e-8e40-4c36-a879-6d68773822fc
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
crates/vize/tests/check_server_cli.rscrates/vize_canon/src/virtual_ts/expressions.rscrates/vize_canon/src/virtual_ts/expressions/component_props.rscrates/vize_canon/src/virtual_ts/expressions/component_props_tests.rscrates/vize_canon/src/virtual_ts/expressions/prop_sources.rstests/performance/misskey-lsp-incremental.test.tstests/tooling/lsp-typecheck-template.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
- GitHub Check: Codesmith
- GitHub Check: tool-benchmark
- GitHub Check: app-readiness
- GitHub Check: pr-benchmark
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: dialect-guard
🧰 Additional context used
📓 Path-based instructions (2)
tests/tooling/**
⚙️ CodeRabbit configuration file
tests/tooling/**: Ensure workflow and release tests assert observable behavior rather than incidental formatting. Prefer focused assertions that keep PRs small and failures easy to diagnose.
Files:
tests/tooling/lsp-typecheck-template.test.ts
crates/**
⚙️ CodeRabbit configuration file
crates/**: Focus on parser/compiler correctness, source locations, UTF-8/UTF-16 offset handling, and panic-free LSP behavior. Flag changes that only work for small fixtures but break real Vue/Nuxt projects.
Files:
crates/vize/tests/check_server_cli.rscrates/vize_canon/src/virtual_ts/expressions.rscrates/vize_canon/src/virtual_ts/expressions/prop_sources.rscrates/vize_canon/src/virtual_ts/expressions/component_props_tests.rscrates/vize_canon/src/virtual_ts/expressions/component_props.rs
🔇 Additional comments (12)
crates/vize_canon/src/virtual_ts/expressions/prop_sources.rs (4)
16-29: LGTM!
31-52: LGTM!
54-66: LGTM!
68-96: LGTM!crates/vize_canon/src/virtual_ts/expressions.rs (1)
9-9: LGTM!crates/vize_canon/src/virtual_ts/expressions/component_props.rs (2)
10-10: LGTM!
143-165: LGTM!crates/vize_canon/src/virtual_ts/expressions/component_props_tests.rs (2)
42-86: LGTM!
120-143: LGTM!crates/vize/tests/check_server_cli.rs (1)
129-129: LGTM!tests/performance/misskey-lsp-incremental.test.ts (2)
154-159: LGTM!
262-262: LGTM!Also applies to: 281-286
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9477 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9478 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9478 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
PR BenchmarkBase:
Raw run timesCompile SFC
Lint
Format
Type check (1T)
Type check (max)
|
Detailed Test ReportCommit: Area Summary
Test InventoryTotal tracked cases: 9478 across 1465 files.
Files
Comment truncated at 64000 characters. Open the workflow run for the full job log. |
Tool BenchmarkMeasured: 2026-07-22T06:15:26.203Z
Fairness notes:
Commands: gh workflow run tool-benchmark.yml --ref <branch> -f file_count=3000 -f check_file_count=500 -f vite_file_count=1000 -f nuxt_file_count=250 -f large_blocks=300 -f runs=3 -f warmups=1 -f commit_results=true
node bench/generate.mjs 3000
node bench/compare-tools.mjs --input bench/__in__ --vize-bin target/release/vize --runs 3 --warmups 1 --check-file-count 500 --vite-file-count 1000 --nuxt-file-count 250 --large-blocks 300 --runner-label "blacksmith-32vcpu-ubuntu-2404" --out tool-benchmark-summary.md --json tool-benchmark-results.json --doc performance-blacksmith.mdVariant details and raw run timesSFC compile
Large SFC compile
Large SFC type check
Lint
Format
Type check
Vite build (end-to-end)
Nuxt SPA build (end-to-end)
|
Summary
Completes divergence 2 of the Tier S report in #2971. After #3201 moved batch diagnostics onto the exact-expression sub-spans, both engines still disagreed by two columns: vue-tsc anchors a component prop-type error at the attribute name, while the check identifier's sub-span pointed at the authored value.
Change
The per-prop check statement now carries two sub-spans:
v-bind:/:prefix so a prop namedbindcannot anchor insidev-bind:and a.camel-style modifier cannot steal the match;Verification
defineProps<{ msg: string }>+:msg="42"/:msg="count"): vize11:18/12:18— byte-identical tovue-tsc(11,18)/(12,18).6:18→6:11, the 1-based column ofcountin:count="'oops'".v-bind:bind/:sync.camelprefix/modifier edge cases.vize_canon636 tests andvize_maestro553 tests green; the language server inherits the same anchors through the shared mapping module.This supersedes the anchor-choice handoff noted in the #2971 comment — with the maintainer-requested completion of the issue, both engines now agree byte-for-byte on prop-type positions.
Part of #2971
Need help on this PR? Tag
/codesmithwith what you need. Autofix is enabled.Summary by CodeRabbit
v-bind:shorthand and directive/modifier variants), including correct UTF-8 byte offset handling.