fix(linter/plugins): fix interaction between JS plugins and Vue rules (#26080)
While working on #26077, Claude spotted another related bug. JS plugins have to run last because they need to mutate the AST, and in the process they destroy the stored AST. For files with multiple sections (Vue, Astro, Svelte), we ran native rules then JS rules for each section in turn. That appeared fine - JS rules do run last. But the problem is that some rules e.g. `vue/valid-define-emits` also access _earlier_ sections. Because JS plugins already ran on those previous sections, their ASTs have been discarded already, leading to incorrect results. Instead, lint in 3 separate passes which each run on _all_ sections before going on to the next pass: 1. Native rules. 2. JS rules. 3. Unused directives. i.e.: - Before: section 1 native, section 1 JS, section 2 native, section 2 JS. - After: section 1 native, section 2 native, section 1 JS, section 2 JS. Unused directives check has to be in a separate final pass, as it requires both native rules and JS rules to have run before it. Looping over sections is cheap compared to the work that happens in each turn of the loops, so I very much doubt this has a measurable impact on perf. This change does have one visible effect: The order of diagnostics will change for multi-section files. Previously diagnostics would be output in section order, now they're in rule type (native/JS) order. I don't _think_ that matters.
O
overlookmotel committed
047f7ca3b5a0a4ec8f16ff6b9cb848535803cf33
Parent: b13215f