(languages: Language[])
| 187 | * Must be called after initGrammars(). |
| 188 | */ |
| 189 | export async function loadGrammarsForLanguages(languages: Language[]): Promise<void> { |
| 190 | if (!parserInitialized) { |
| 191 | await initGrammars(); |
| 192 | } |
| 193 | |
| 194 | // SFC languages (svelte/vue/astro) have no grammar of their own — their |
| 195 | // extractors delegate <script>/frontmatter content to the TS/JS extractor, |
| 196 | // so those grammars must be loaded even when no plain .ts/.js file is in |
| 197 | // the index set (e.g. a pure-.astro content site). |
| 198 | if (languages.some((l) => l === 'svelte' || l === 'vue' || l === 'astro')) { |
| 199 | languages = [...languages, 'typescript', 'javascript']; |
| 200 | } |
| 201 | |
| 202 | // Deduplicate and filter to languages that have WASM grammars and aren't already loaded |
| 203 | const toLoad = [...new Set(languages)].filter( |
| 204 | (lang): lang is GrammarLanguage => |
| 205 | lang in WASM_GRAMMAR_FILES && |
| 206 | !languageCache.has(lang) && |
| 207 | !unavailableGrammarErrors.has(lang) |
| 208 | ); |
| 209 | |
| 210 | // Load grammars sequentially to avoid web-tree-sitter WASM race condition on Node 20+ |
| 211 | // See: https://github.com/tree-sitter/tree-sitter/issues/2338 |
| 212 | for (const lang of toLoad) { |
| 213 | const wasmFile = WASM_GRAMMAR_FILES[lang]; |
| 214 | try { |
| 215 | // Some grammars ship their own WASMs (not in tree-sitter-wasms, or the |
| 216 | // tree-sitter-wasms build is too old). Lua: tree-sitter-wasms ships an |
| 217 | // ABI-13 build that corrupts the shared WASM heap under web-tree-sitter |
| 218 | // 0.25 (drops nested calls/imports on every file after the first); we |
| 219 | // vendor the upstream ABI-15 wasm instead. C#: the tree-sitter-wasms |
| 220 | // build (ABI 13) has no primary-constructor support and parses |
| 221 | // `class Foo(...)` as an ERROR that swallows the whole class (#237); we |
| 222 | // vendor the upstream ABI-15 tree-sitter-c-sharp 0.23.5 wasm, which parses |
| 223 | // primary constructors natively. |
| 224 | const wasmPath = (lang === 'pascal' || lang === 'scala' || lang === 'lua' || lang === 'luau' || lang === 'csharp' || lang === 'r') |
| 225 | ? path.join(__dirname, 'wasm', wasmFile) |
| 226 | : require.resolve(`tree-sitter-wasms/out/${wasmFile}`); |
| 227 | const language = await WasmLanguage.load(wasmPath); |
| 228 | languageCache.set(lang, language); |
| 229 | } catch (error) { |
| 230 | const message = error instanceof Error ? error.message : String(error); |
| 231 | console.warn(`[CodeGraph] Failed to load ${lang} grammar — parsing will be unavailable: ${message}`); |
| 232 | unavailableGrammarErrors.set(lang, message); |
| 233 | } |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | /** |
| 238 | * Load ALL grammar WASM files. Convenience function for tests and |
no test coverage detected