You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Svelte <script> function/call symbols never extracted — component call-graph is empty (imports work per #223, calls don't; Svelte analog of #1410) #1807
For .svelte components, the <script>/<script lang="ts"> block is parsed structurally but its function definitions and call sites are never emitted as graph symbols. Each component yields only File + Module nodes. Imports are extracted (thanks to #223/#224) and SvelteKit routes too (#369), but the call graph inside components is absent.
This is the Svelte analog of #1410 (Vue <script setup>), with the same consequence: incomplete call graph and false-positive dead-code for component logic.
Index any repo containing a .svelte component whose <script lang="ts"> defines named functions (e.g. function toggleOpen() {…}).
Query the graph:
query_graph MATCH (f:Function) WHERE f.file_path ENDS WITH '.svelte' RETURN count(*)
query_graph MATCH (n) WHERE n.file_path ENDS WITH '.svelte' RETURN n.name, labels(n)
Real-world index (a SvelteKit app, 294 components): 294/294 components have File+Module nodes and import edges, but zero<script>-internal function or call symbols.
Expected
<script> bodies re-parsed as JS/TS (language injection on script_element → TS grammar), with normal symbol + CALLS/DEFINES extraction and line offsets mapped back to the component — matching what already happens for a .ts file.
Evidence that injection is sufficient
Extracting a component's <script> verbatim into a sibling .ts file makes the same functions appear as full Function nodes with call edges:
Source
Function nodes emitted
TreeNode.svelte (toggleOpen, transformDataForRecursiveTree in <script>)
0
identical body extracted to TreeNode.script.ts
2 (both, with edges)
So the grammar + extractor already handle the code — only the injection step from script_element into TS symbol/call extraction is missing (the imports path added in #223 is the precedent).
Thank you for this — it is an unusually complete first report, and the A/B table is what makes it immediately actionable. Showing the same code producing two Function nodes as .ts and zero inside a .svelte<script> block isolates the problem exactly, with no guesswork left for us.
You have diagnosed it correctly. Imports work because that path already handles the component wrapper (#223/#224), but the <script> block's contents are never handed to the TypeScript extractor, so no function or call symbols come out of it. The component call-graph is empty for precisely that reason.
This is the same root cause as #1410, which reports it for Vue's <script setup>. Both need the same fix — injecting the embedded script region into the TS extractor rather than treating the component file as opaque past its imports — so I am linking them and they should be fixed together rather than separately. Your report and that one arrived from different angles at the same missing piece, which is good corroboration that it is worth doing properly rather than patching per-framework.
No action needed from you. I will update both issues when the work is scheduled.
One small note, purely so it does not surprise you: this issue briefly tripped our automated content screening, because the title contains <script> and a title cannot be code-formatted on GitHub. That was a false positive on our side and it has been fixed — the scanner now recognises a bare tag name in a title as inert. Nothing was wrong with how you wrote it, and it is a good illustration of why a tool that parses markup languages needs its own tooling to expect markup in bug reports.
Thanks again for taking the time to build the repro.
Update, and a correction to what I told you earlier.
I said #1410 and this issue "should be fixed together rather than separately". The Vue half has now landed on main in e678722 (#1852) — and it does not fix Svelte. I want to be straight about that rather than let you find it out from a release note.
What that change actually built is the shared machinery, which is the part that was worth doing properly: it parses the embedded <script> region through ts_parser_set_included_ranges against the original buffer, so definitions and calls come out with correct byte and point coordinates (a naive re-slice gets both subtly wrong across CRLF and BOM), and it resolves lang="ts" / lang="js" and bails on src=. Svelte, HTML and Astro already declare the identical embedded-block spec, so the seam now works for them too — what is still switched off is structural extraction, which is gated on one boolean.
Being fully honest about the current state: that change ships a control test asserting Svelte, HTML and Astro still produce zero functions and zero calls. That is your bug, pinned as expected behaviour. It is there so the follow-up has something to flip, not because we think it is correct — but you should know it is written down that way today.
The follow-up is under way. @bmcnaboe proposed the generalization on #1410 independently and has a 212-SFC corpus to validate it against, so I have asked them to carry it and given them the remaining detail. I have not put a deadline on them, so I cannot give you a firm date. What I can commit to is this: I will report back here either way rather than leave it open-ended, and if it stalls we will land it ourselves.
Your A/B table is still the thing that made this actionable, and the fix that lands will be verified by flipping that control test to assert exactly what your report says should happen. Thank you for the patience.
The generalization is up as #2056 — Svelte, HTML and Astro <script> blocks (and Astro's frontmatter fence) now extract definitions and calls in file coordinates, and the control test from #1852 is flipped to assert exactly the symbols your A/B table shows. Validated against the Vue corpus with identical results before and after. Thanks for the report; the two-row table is what made it precise.
Activity
DeusData commentedon Aug 26, 2026
Thank you for this — it is an unusually complete first report, and the A/B table is what makes it immediately actionable. Showing the same code producing two
Functionnodes as.tsand zero inside a.svelte<script>block isolates the problem exactly, with no guesswork left for us.You have diagnosed it correctly. Imports work because that path already handles the component wrapper (#223/#224), but the
<script>block's contents are never handed to the TypeScript extractor, so no function or call symbols come out of it. The component call-graph is empty for precisely that reason.This is the same root cause as #1410, which reports it for Vue's
<script setup>. Both need the same fix — injecting the embedded script region into the TS extractor rather than treating the component file as opaque past its imports — so I am linking them and they should be fixed together rather than separately. Your report and that one arrived from different angles at the same missing piece, which is good corroboration that it is worth doing properly rather than patching per-framework.No action needed from you. I will update both issues when the work is scheduled.
One small note, purely so it does not surprise you: this issue briefly tripped our automated content screening, because the title contains
<script>and a title cannot be code-formatted on GitHub. That was a false positive on our side and it has been fixed — the scanner now recognises a bare tag name in a title as inert. Nothing was wrong with how you wrote it, and it is a good illustration of why a tool that parses markup languages needs its own tooling to expect markup in bug reports.Thanks again for taking the time to build the repro.
DeusData commentedon Aug 27, 2026
Update, and a correction to what I told you earlier.
I said #1410 and this issue "should be fixed together rather than separately". The Vue half has now landed on
mainin e678722 (#1852) — and it does not fix Svelte. I want to be straight about that rather than let you find it out from a release note.What that change actually built is the shared machinery, which is the part that was worth doing properly: it parses the embedded
<script>region throughts_parser_set_included_rangesagainst the original buffer, so definitions and calls come out with correct byte and point coordinates (a naive re-slice gets both subtly wrong across CRLF and BOM), and it resolveslang="ts"/lang="js"and bails onsrc=. Svelte, HTML and Astro already declare the identical embedded-block spec, so the seam now works for them too — what is still switched off is structural extraction, which is gated on one boolean.Being fully honest about the current state: that change ships a control test asserting Svelte, HTML and Astro still produce zero functions and zero calls. That is your bug, pinned as expected behaviour. It is there so the follow-up has something to flip, not because we think it is correct — but you should know it is written down that way today.
The follow-up is under way. @bmcnaboe proposed the generalization on #1410 independently and has a 212-SFC corpus to validate it against, so I have asked them to carry it and given them the remaining detail. I have not put a deadline on them, so I cannot give you a firm date. What I can commit to is this: I will report back here either way rather than leave it open-ended, and if it stalls we will land it ourselves.
Your A/B table is still the thing that made this actionable, and the fix that lands will be verified by flipping that control test to assert exactly what your report says should happen. Thank you for the patience.
fix(extract): extract structure from Vue inline scripts
bmcnaboe commentedon Sep 4, 2026
The generalization is up as #2056 — Svelte, HTML and Astro
<script>blocks (and Astro's frontmatter fence) now extract definitions and calls in file coordinates, and the control test from #1852 is flipped to assert exactly the symbols your A/B table shows. Validated against the Vue corpus with identical results before and after. Thanks for the report; the two-row table is what made it precise.DeusData commentedon Sep 6, 2026
Fixed on main by 2b030a5 (#2056, thanks to @bmcnaboe): structure inside Svelte, HTML and Astro inline scripts is now extracted.
fix(extract): extract structure from Svelte/HTML/Astro inline scripts
fix(extract): extract structure from Svelte/HTML/Astro inline scripts