feat(container): index .vue SFCs via their <script> block - #101
Open
davidpru wants to merge 1 commit into
Open
Conversation
A .vue file is not a language, it is a wrapper around one, and everything worth indexing lives inside its <script>. Registering tree-sitter-vue as a breadth-tier language would not help: that grammar parses the shell (template/script/style) and hands back the script body as one opaque raw_text node, so the cards would come out empty. So the container grammar is used only to answer "where does the embedded language start and end", and the block itself goes to the DEPTH-tier extractor. A .vue file gets the same quality of extraction as a .ts file — bindings, imports, resolved calls — rather than the signature-only output the breadth tier gives. On the repo that prompted this, edges went from 863 to 2465, because calls from components into .ts modules now resolve. The span shift was the part flagged as risky, and it is subtler than it looks: raw_text starts immediately after the `>` of the opening tag, so its row IS the tag's row and the slice begins with that line's newline. Script line N therefore lands on .vue line row + N, which is exactly "add the start row to a 1-based span". Taking the row from the script_element instead looks equivalent and is right only when the tag carries no attributes — that is, never in practice. Verified beyond the fixtures: across the 91 .vue files of a real Laravel + Vue app, every one of the 270 extracted symbols has its name on the line its span points to, and the 60 files that yield nothing yield nothing as .ts either. Also updates the NanoNets#98 tests, which used .vue as their unsupported-extension example — that example had to move to .svelte now that .vue has a parser, and supportedExtensions() had to learn about the container tier so the new -e warning does not contradict the new feature. Two small exports from generic.ts (loadWasmLanguage, parseWasm) let the container share the wasm plumbing instead of initialising web-tree-sitter a second time. Svelte and Astro are the same shape and would be a registry row each, but they are left out until someone has a repo to verify them against: a wrong `body` node type would produce silently misplaced spans, which is worse than no support.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A .vue file is not a language, it is a wrapper around one, and everything worth indexing lives inside its <script>. Registering tree-sitter-vue as a breadth-tier language would not help: that grammar parses the shell (template/script/style) and hands back the script body as one opaque raw_text node, so the cards would come out empty.
So the container grammar is used only to answer "where does the embedded language start and end", and the block itself goes to the DEPTH-tier extractor. A .vue file gets the same quality of extraction as a .ts file — bindings, imports, resolved calls — rather than the signature-only output the breadth tier gives. On the repo that prompted this, edges went from 863 to 2465, because calls from components into .ts modules now resolve.
The span shift was the part flagged as risky, and it is subtler than it looks: raw_text starts immediately after the
>of the opening tag, so its row IS the tag's row and the slice begins with that line's newline. Script line N therefore lands on .vue line row + N, which is exactly "add the start row to a 1-based span". Taking the row from the script_element instead looks equivalent and is right only when the tag carries no attributes — that is, never in practice.Verified beyond the fixtures: across the 91 .vue files of a real Laravel + Vue app, every one of the 270 extracted symbols has its name on the line its span points to, and the 60 files that yield nothing yield nothing as .ts either.
Also updates the #98 tests, which used .vue as their unsupported-extension example — that example had to move to .svelte now that .vue has a parser, and supportedExtensions() had to learn about the container tier so the new -e warning does not contradict the new feature.
Two small exports from generic.ts (loadWasmLanguage, parseWasm) let the container share the wasm plumbing instead of initialising web-tree-sitter a second time.
Svelte and Astro are the same shape and would be a registry row each, but they are left out until someone has a repo to verify them against: a wrong
bodynode type would produce silently misplaced spans, which is worse than no support.