feat(parsing): add Svelte parser#105
Conversation
- Add tree-sitter-svelte-next = "0.1.1" dependency
- New src/parsing/svelte/: SvelteParser, SvelteBehavior, SvelteLanguage
- SvelteParser re-parses <script> block via JavaScriptParser with line-offset correction
- Snippet functions ({#snippet name}) extracted from Svelte AST as Function symbols
- Language::Svelte wired into registry, factory, and extension detection (.svelte)
|
❌ Quick checks failure |
Add Svelte arm to the tree-sitter language match in io/parse.rs and to the standalone parser factory match in factory.rs.
|
Hey @antono, thanks for tackling Svelte! A few things worth a second pass: running nix flake update (or your local rustup) will bump to 1.95+ and unblock the 5 unit tests in parser.rs. Could you paste the passing cargo test output here just to confirm the offset math checks out? resolution.rs: Delegating to JS makes sense, but since our standard pattern (Lua, Go, Python) ships the four-file set, could you either wrap JavaScriptResolutionContext in a SvelteResolutionContext, or just add a quick note in audit pipeline: Every existing language ships since <script lang="ts"> is the default in Svelte 5, we should either support it now (re-parsing with TypeScriptParser), or explicitly scope this PR to JS-only and track TS support in a follow-up issue. as you did with the Nix PR, let's add an examples/svelte/comprehensive.svelte file. Ideally, it should include imports, snippets, functions, $state / $derived, and both js/ts blocks to give the parser a proper stress test during review. Thanks again |
Summary
.sveltefile support via a newSvelteParserthat usestree-sitter-svelte-nextto locate<script>blocks and re-parses their content with the existingJavaScriptParser.sveltefile, not the script fragment{#snippet name(...)}blocks are detected directly in the Svelte AST and emitted asFunctionsymbolstree-sitter-svelte-next = "0.1.1"Files changed
src/parsing/svelte/parser.rsfind_*delegation to JS sub-parsersrc/parsing/svelte/behavior.rsLanguageBehavior— visibility viaexport, source roots for SvelteKit layoutsrc/parsing/svelte/definition.rsLanguageDefinitionregistration,is_enabled()config checksrc/parsing/svelte/mod.rsregister()src/parsing/language.rsLanguage::Svelteenum variant +extensions,config_key,namesrc/parsing/mod.rspub mod svelte+ re-exportssrc/parsing/registry.rssuper::svelte::register(registry)ininitialize_registry()src/parsing/factory.rsLanguage::Sveltematch arm increate_parser_with_behavior()andenabled_languages()Design notes
Why re-parse with JavaScriptParser instead of walking the Svelte tree?
The
tree-sitter-svelte-nextgrammar represents<script>content as an opaqueraw_textnode — there is no embedded JS/TS subtree. Re-parsing the raw text withJavaScriptParserreuses all existing JS symbol extraction, call/import/method-call logic, and future improvements for free.Range offset:
raw_text.start_position()gives the file-level row/column where the script begins. Every range produced by the JS sub-parser is shifted by this offset. Only the first line of a multi-line symbol gets the column offset applied (subsequent lines start at column 0 in the source).Test results
Tested against 11 real
.sveltefiles from two GitHub projects (svelte-realworldandsvelte/examples). All files parsed with zero tree-sitter errors.Assertions (all PASSED ✓)
Symbol extraction summary
Nav.svelte$app/state)Pagination.svelterange(Constant),result(Constant),i(Variable)+layout.svelte+page.svelte(realworld)Counter.svelte(svelte 5)increment(Function),decrement(Function)+page.svelte(todomvc)+page.svelte(file-uploads)handle_large_submit(Function)Note on in-crate unit tests
src/parsing/svelte/parser.rscontains 5 unit tests (test_svelte_parser_loads,test_validate_grammar_node_kinds,test_parse_script_symbols,test_snippet_symbols,test_range_offset). These cannot run locally becausesysinfo@0.39.2(an existing dependency) requires rustc 1.95+, while the current Nix flake provides 1.94.0. The tests are expected to pass once the flake toolchain is updated.