Skip to content

feat(container): index .vue SFCs via their <script> block - #101

Open
davidpru wants to merge 1 commit into
NanoNets:mainfrom
davidpru:feat/vue-sfc-container
Open

feat(container): index .vue SFCs via their <script> block#101
davidpru wants to merge 1 commit into
NanoNets:mainfrom
davidpru:feat/vue-sfc-container

Conversation

@davidpru

Copy link
Copy Markdown

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 body node type would produce silently misplaced spans, which is worse than no support.

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.
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.

1 participant