Last 12 weeks ยท 42 commits
3 of 6 standards met
Summary Previously, both and returned from , which meant TypeScript had to fully reparse every file on each snapshot update. This PR implements properly, enabling TypeScript's built-in incremental parser. What changed New function* โ a simple linear scan (using for speed) that finds the minimal diff between old and new text, returning a with the exact changed span. โ now computes the change range between the old snapshot's text and the current text instead of returning . โ same as above, with an additional optimization: when TS passes the same object reference (which happens because mutates the snapshot in-place and TS cached the reference before mutation), it returns a pre-computed change range from the last call, avoiding a redundant diff. 31 unit tests covering correctness and integration for both snapshot types. How works Why this matters is called by TypeScript every time a source file snapshot changes. Previously returning forced a full reparse of the entire file. With a proper change range, TypeScript's incremental parser can: 1. Reuse unchanged AST nodes โ only re-parsing the region that actually changed 2. Skip reparsing entirely for token-level edits where the AST structure is unchanged In end-to-end benchmarks (including svelte2tsx, parseHTML, and TS program update), this yields roughly a 5-10% improvement* in the full update pipeline. Test plan [x] All 31 unit tests pass ( in ) [ ] Manual testing in VS Code with Svelte extension on a large project ๐ค Generated with Claude Code
Repository: sveltejs/language-tools. Description: The Svelte Language Server, and official extensions which use it Stars: 1403, Forks: 230. Primary language: TypeScript. Languages: TypeScript (80.4%), JavaScript (14.7%), Svelte (4.9%). License: MIT. Topics: language-server, svelte, vscode-extension. Latest release: svelte-language-server@0.17.29 (2d ago). Open PRs: 28, open issues: 248. Last activity: 2d ago. Community health: 62%. Top contributors: dummdidumm, jasonlyu123, jamesbirtles, orta, halfnelson, pushkine, github-actions[bot], paoloricciuti, benmccann, dependabot[bot] and others.
TypeScript
Summary Cache internal ASTs across invocations and use for incremental reparsing instead of on every call The language server maintains a per-file cache that is passed through to , enabling TypeScript to reuse unchanged AST subtrees Falls back to full parsing when no prior AST is available or content is unchanged Benchmark results Isolated svelte2tsx (80 sequential single-char edits, realistic ~100 line component): Full LSP round-trip (type char โ hover): Median: 3.1ms โ the cache saves ~0.2-0.5ms per request, with the TS language service being the dominant cost How it works Inside , there are two calls that parse `svelte2tsxts.updateSourceFile(oldAst, newText, changeRange)Svelte2TsxCachecomputeScriptChangeRange()ts.TextChangeRangegetOrUpdateSourceFile()ts.updateSourceFile()ts.createSourceFile()ts.updateSourceFile()` preserves parent node references [x] Verified fallback to full parse when cache is empty or content unchanged ๐ค Generated with Claude Code
Summary accounts for ~10% of wall-clock time Most consumers never need the source map on the hot path: Language server: , , don't use the map. The mapper is already lazily initialized, but the map object itself was eagerly computed. svelte-check incremental mode: only uses , never The property is now a lazy getter that calls on first access and caches the result via Consumers that do access (TypeScript plugin, sourcemap tests) see no regression โ the map is generated once on first access Benchmarks Measured with realistic generated Svelte components of various sizes: Test plan [x] All 365 svelte2tsx tests pass (including 16 sourcemap tests) [x] All 665 language-server tests pass ๐ค Generated with Claude Code
Describe the bug does not pass to the Svelte compiler's call. This means warning.filename is always undefined inside , making path-based filtering impossible. In https://github.com/sveltejs/language-tools/issues/855#issuecomment-2260878498, was demonstrated (maybe just aspirational) as a supported use case: Note that in the same file () does correctly pass . Reproduction output shows the filename in its diagnostic output, but inside is . The root cause is in https://github.com/sveltejs/language-tools/blob/master/packages/language-server/src/plugins/svelte/SvelteDocument.ts: Expected behaviour warning.filename should contain the file path. Suggested fix: System Info OS: macOS IDE: N/A (svelte-check CLI) svelte-check: 4.4.3 svelte: 5.53.1 Which package is the issue about? svelte-check, svelte-language-server Additional Information, eg. Screenshots _No response_