@wrongstack/tools 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/builtin.js +15 -15
  2. package/dist/{chunk-GU7TZE6Z.js → chunk-2BCRQAIW.js} +7 -7
  3. package/dist/{chunk-XRNN44QY.js → chunk-2IRHFHZY.js} +235 -71
  4. package/dist/{chunk-NEYUPZL6.js → chunk-6D3UIQMF.js} +651 -303
  5. package/dist/chunk-BJ5LXLKE.js +351 -0
  6. package/dist/{chunk-C6ZOXNXV.js → chunk-CSS42GRP.js} +2 -2
  7. package/dist/{chunk-SKRMUHTU.js → chunk-HSLDY55L.js} +41 -8
  8. package/dist/{chunk-ENE22I5W.js → chunk-K37AKCTN.js} +884 -362
  9. package/dist/{chunk-DKXMDO5F.js → chunk-K3VX6V5P.js} +3 -3
  10. package/dist/chunk-OIFY4XNP.js +855 -0
  11. package/dist/{chunk-7GOE2ZTZ.js → chunk-OMWC2OGT.js} +2 -2
  12. package/dist/{chunk-IE4KDAOB.js → chunk-OYQE2UNT.js} +3 -3
  13. package/dist/chunk-R3HR3QI3.js +97 -0
  14. package/dist/{chunk-XPVYZ2S6.js → chunk-RYLMSGR5.js} +2 -2
  15. package/dist/{chunk-HYHE4VNA.js → chunk-UMOP3VGK.js} +79 -45
  16. package/dist/{chunk-6OIEYJM4.js → chunk-VMNWQI4V.js} +2 -2
  17. package/dist/{chunk-2UVAIS5O.js → chunk-YPSVPCIE.js} +2 -2
  18. package/dist/{chunk-PWZUHZP7.js → chunk-Z77XMU3U.js} +2 -2
  19. package/dist/codebase-index/ast-invariant-engine.d.ts +19 -2
  20. package/dist/codebase-index/atlas-projection.d.ts +19 -0
  21. package/dist/codebase-index/background-indexer.d.ts +14 -0
  22. package/dist/codebase-index/circuit-breaker.d.ts +7 -0
  23. package/dist/codebase-index/codebase-ast-replace-tool.d.ts +1 -1
  24. package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +6 -0
  25. package/dist/codebase-index/codebase-invariant-check-tool.d.ts +2 -0
  26. package/dist/codebase-index/codebase-targeted-test-tool.d.ts +26 -0
  27. package/dist/codebase-index/dead-code-scan.d.ts +4 -0
  28. package/dist/codebase-index/go-parser.d.ts +23 -3
  29. package/dist/codebase-index/graph-rank-pass.d.ts +10 -0
  30. package/dist/codebase-index/graph-rank.d.ts +8 -0
  31. package/dist/codebase-index/index.d.ts +1 -1
  32. package/dist/codebase-index/index.js +9 -9
  33. package/dist/codebase-index/lsp-kind.d.ts +3 -1
  34. package/dist/codebase-index/module-resolver.d.ts +21 -1
  35. package/dist/codebase-index/parser-batch.d.ts +6 -8
  36. package/dist/codebase-index/parser-output.d.ts +5 -1
  37. package/dist/codebase-index/parser-worker-script.js +4 -4
  38. package/dist/codebase-index/project-server-framing.d.ts +1 -17
  39. package/dist/codebase-index/project-server-watcher.d.ts +6 -0
  40. package/dist/codebase-index/project-server.js +72 -26
  41. package/dist/codebase-index/py-parser.d.ts +4 -4
  42. package/dist/codebase-index/rs-parser.d.ts +7 -0
  43. package/dist/codebase-index/toolchain-scripts.d.ts +64 -0
  44. package/dist/codebase-index/tree-sitter/queries.d.ts +14 -0
  45. package/dist/codebase-index/tree-sitter/util.d.ts +6 -1
  46. package/dist/codebase-index/tree-sitter-parser.d.ts +7 -0
  47. package/dist/codebase-index/worker.js +23 -16
  48. package/dist/codebase-index/writer-refs.d.ts +17 -2
  49. package/dist/codebase-index/writer-search-helpers.d.ts +9 -0
  50. package/dist/codebase-index/writer.d.ts +20 -1
  51. package/dist/edit.js +8 -8
  52. package/dist/{generic-parser-N2PLGBC2.js → generic-parser-IVWLFKMR.js} +2 -2
  53. package/dist/go-parser-LWV3L5V7.js +197 -0
  54. package/dist/index.js +17 -17
  55. package/dist/json-parser-PERV2JHX.js +204 -0
  56. package/dist/pack.js +16 -16
  57. package/dist/parser-dispatch-ZSWCQB6M.js +14 -0
  58. package/dist/patch.js +8 -8
  59. package/dist/{py-parser-4PFZYAJ7.js → py-parser-B6D6RGH7.js} +4 -4
  60. package/dist/read.js +8 -8
  61. package/dist/replace.js +8 -8
  62. package/dist/rs-parser-L7SP4GWJ.js +182 -0
  63. package/dist/tool-tier.js +17 -17
  64. package/dist/{tree-sitter-parser-GILYQLS4.js → tree-sitter-parser-KU6JF3ZC.js} +6 -4
  65. package/dist/{ts-parser-7W26YB26.js → ts-parser-PML6QIH7.js} +55 -23
  66. package/dist/write.js +8 -8
  67. package/dist/{yaml-parser-DFBC5FWH.js → yaml-parser-7BJN544B.js} +41 -6
  68. package/package.json +5 -5
  69. package/dist/chunk-4CE3RKEP.js +0 -390
  70. package/dist/chunk-KHUCKLOR.js +0 -899
  71. package/dist/chunk-ZKC5UNGD.js +0 -167
  72. package/dist/go-parser-Z4H6SR3R.js +0 -474
  73. package/dist/json-parser-IJD77VL4.js +0 -256
  74. package/dist/parser-dispatch-WG4DNBHH.js +0 -14
  75. package/dist/rs-parser-GIWPUA3T.js +0 -81
@@ -0,0 +1,351 @@
1
+ import {
2
+ resolvePythonBinary
3
+ } from "./chunk-R3HR3QI3.js";
4
+ import {
5
+ GO_BATCH_SCRIPT,
6
+ PY_BATCH_SCRIPT,
7
+ goSpawnOptions,
8
+ parseParserBatchOutput,
9
+ privateScriptPath,
10
+ pySpawnOptions,
11
+ runToolchainChild,
12
+ toIndexSymbols,
13
+ withSpawnGate
14
+ } from "./chunk-OIFY4XNP.js";
15
+ import {
16
+ resolveWin32Command
17
+ } from "./chunk-XZLVJD56.js";
18
+
19
+ // src/codebase-index/import-extractor.ts
20
+ var IMPORT_MAX_FILE_CHARS = 512 * 1024;
21
+ var IMPORT_MAX_PER_FILE = 400;
22
+ var DOTTED_IMPORT = [
23
+ { re: /^[ \t]*import\s+(?:static\s+)?([\w.]+(?:\.\*)?)\s*;?\s*$/gm }
24
+ ];
25
+ var LANG_IMPORTS = {
26
+ // Go and Python have real AST extractors; these patterns are the fallback for
27
+ // machines with no Go toolchain or Python interpreter installed, where the
28
+ // parser degrades to regex symbols and would otherwise contribute no edges.
29
+ go: [
30
+ { re: /^[ \t]*import\s+(?:[\w.]+\s+)?"([^"]+)"/gm },
31
+ // Grouped form: inside `import ( … )` each line is an optional alias plus a
32
+ // quoted path. A stray match elsewhere resolves to no file and is dropped.
33
+ { re: /^[ \t]*(?:[A-Za-z_.]\w*\s+)?"([^"]+)"\s*$/gm }
34
+ ],
35
+ py: [{ re: /^[ \t]*import\s+([\w.]+)/gm }, { re: /^[ \t]*from\s+([.\w]+)\s+import\b/gm }],
36
+ rs: [
37
+ // use a::b::C; | use a::b::{C, D}; | use a::b::*; → the path before
38
+ // any brace or glob. Visibility may be restricted (`pub(crate) use …`),
39
+ // which the plain `pub\s+` form never matched.
40
+ { re: /^[ \t]*(?:pub(?:\s*\([^)]*\))?\s+)?use\s+(?:::)?([\w:]+?)(?:::\{|::\*|\s*;|\s+as\b)/gm },
41
+ // mod foo; (a declaration *and* a dependency on foo.rs / foo/mod.rs)
42
+ { re: /^[ \t]*(?:pub(?:\s*\([^)]*\))?\s+)?mod\s+(\w+)\s*;/gm }
43
+ ],
44
+ java: DOTTED_IMPORT,
45
+ kotlin: DOTTED_IMPORT,
46
+ scala: [{ re: /^[ \t]*import\s+([\w.]+(?:\.[_*])?)\s*$/gm }],
47
+ csharp: [
48
+ // using Foo.Bar; | using static Foo.Bar; | using Alias = Foo.Bar;
49
+ { re: /^[ \t]*global\s+using\s+(?:static\s+)?([\w.]+)\s*;/gm, name: "full" },
50
+ { re: /^[ \t]*using\s+(?:static\s+)?(?:\w+\s*=\s*)?([\w.]+)\s*;/gm, name: "full" }
51
+ ],
52
+ // Quoted includes only: <stdio.h> is a system header with no indexed file.
53
+ c: [{ re: /^[ \t]*#\s*include\s+"([^"]+)"/gm }],
54
+ cpp: [{ re: /^[ \t]*#\s*include\s+"([^"]+)"/gm }],
55
+ ruby: [{ re: /^[ \t]*(?:require|require_relative|load)\s*\(?\s*['"]([^'"]+)['"]/gm }],
56
+ php: [
57
+ // `use A\B\C` imports the class C, which is what the index has a symbol
58
+ // for — the namespace symbol only covers the `A\B` prefix.
59
+ { re: /^[ \t]*use\s+(?:function\s+|const\s+)?([\w\\]+)/gm },
60
+ { re: /^[ \t]*(?:require|require_once|include|include_once)\s*\(?\s*['"]([^'"]+)['"]/gm }
61
+ ],
62
+ swift: [{ re: /^[ \t]*import\s+(?:struct\s+|class\s+|func\s+)?([\w.]+)\s*$/gm }],
63
+ dart: [{ re: /^[ \t]*(?:import|export|part)\s+['"]([^'"]+)['"]/gm }],
64
+ lua: [{ re: /\brequire\s*\(?\s*['"]([^'"]+)['"]/g }],
65
+ elixir: [{ re: /^[ \t]*(?:alias|import|require|use)\s+([A-Z][\w.]*)/gm, name: "full" }],
66
+ haskell: [{ re: /^[ \t]*import\s+(?:qualified\s+)?([\w.]+)/gm, name: "full" }],
67
+ zig: [{ re: /@import\s*\(\s*"([^"]+)"\s*\)/g }],
68
+ proto: [{ re: /^[ \t]*import\s+(?:public\s+|weak\s+)?"([^"]+)"\s*;/gm }],
69
+ // `@import "x"`, `@use "x"`, `@forward "x"` — Sass and plain CSS alike.
70
+ css: [{ re: /^[ \t]*@(?:import|use|forward)\s+(?:url\()?\s*['"]([^'"]+)['"]/gm }],
71
+ // A .vue/.svelte file's <script> block is JS; the same ESM syntax applies.
72
+ vue: [{ re: /^[ \t]*import\s[^'"]*from\s*['"]([^'"]+)['"]/gm }],
73
+ svelte: [{ re: /^[ \t]*import\s[^'"]*from\s*['"]([^'"]+)['"]/gm }],
74
+ html: [
75
+ { re: /<script[^>]+src\s*=\s*['"]([^'"]+)['"]/g },
76
+ { re: /<link[^>]+href\s*=\s*['"]([^'"]+)['"]/g }
77
+ ],
78
+ shell: [{ re: /^[ \t]*(?:source|\.)\s+(\S+)/gm }],
79
+ r: [{ re: /\b(?:source|library|require)\s*\(\s*['"]?([\w./-]+)['"]?\s*\)/g }]
80
+ };
81
+ function lastSegment(specifier) {
82
+ const pathLike = /[/\\]|::/.test(specifier);
83
+ const segments = specifier.split(/[/\\]|::/).filter(Boolean);
84
+ let last = segments[segments.length - 1] ?? specifier;
85
+ if (last === "*" || last === "_") {
86
+ last = segments[segments.length - 2] ?? specifier;
87
+ }
88
+ if (pathLike) return last.replace(/\.[A-Za-z0-9]{1,8}$/, "") || last;
89
+ const dotted = last.split(".").filter((part) => part && part !== "*" && part !== "_");
90
+ return dotted[dotted.length - 1] ?? last;
91
+ }
92
+ function newlineOffsets(content) {
93
+ const offsets = [];
94
+ for (let i = 0; i < content.length; i++) {
95
+ if (content.charCodeAt(i) === 10) offsets.push(i);
96
+ }
97
+ return offsets;
98
+ }
99
+ function lineAt(offsets, index) {
100
+ let low = 0;
101
+ let high = offsets.length;
102
+ while (low < high) {
103
+ const mid = low + high >>> 1;
104
+ if ((offsets[mid] ?? 0) < index) low = mid + 1;
105
+ else high = mid;
106
+ }
107
+ return low + 1;
108
+ }
109
+ function hasImportPatterns(lang) {
110
+ return LANG_IMPORTS[lang] !== void 0;
111
+ }
112
+ function extractImports(opts) {
113
+ const patterns = LANG_IMPORTS[opts.lang];
114
+ if (!patterns || !opts.content) return [];
115
+ const limit = opts.maxImports ?? IMPORT_MAX_PER_FILE;
116
+ const content = opts.content.length > IMPORT_MAX_FILE_CHARS ? opts.content.slice(0, IMPORT_MAX_FILE_CHARS) : opts.content;
117
+ const refs = [];
118
+ const seen = /* @__PURE__ */ new Set();
119
+ const offsets = newlineOffsets(content);
120
+ for (const pattern of patterns) {
121
+ const re = new RegExp(pattern.re.source, pattern.re.flags);
122
+ for (const match of content.matchAll(re)) {
123
+ if (refs.length >= limit) return refs;
124
+ const specifier = match[1]?.trim();
125
+ if (!specifier) continue;
126
+ const module = specifier;
127
+ const toName = pattern.name === "full" ? module : lastSegment(module);
128
+ if (!toName) continue;
129
+ const key = `${module}\0${toName}`;
130
+ if (seen.has(key)) continue;
131
+ seen.add(key);
132
+ refs.push({
133
+ fromId: 0,
134
+ toName,
135
+ callType: "import",
136
+ line: lineAt(offsets, match.index ?? 0),
137
+ lang: opts.lang,
138
+ module
139
+ });
140
+ }
141
+ }
142
+ return refs;
143
+ }
144
+
145
+ // src/codebase-index/parser-batch.ts
146
+ var MAX_BATCH_FILES = 100;
147
+ var MAX_BATCH_BYTES = 8 * 1024 * 1024;
148
+ function chunkBatchFiles(files) {
149
+ const chunks = [];
150
+ let current = [];
151
+ let bytes = 0;
152
+ for (const file of files) {
153
+ const size = Buffer.byteLength(file.content, "utf8");
154
+ if (current.length > 0 && (current.length >= MAX_BATCH_FILES || bytes + size > MAX_BATCH_BYTES)) {
155
+ chunks.push(current);
156
+ current = [];
157
+ bytes = 0;
158
+ }
159
+ current.push(file);
160
+ bytes += size;
161
+ }
162
+ if (current.length > 0) chunks.push(current);
163
+ return chunks;
164
+ }
165
+ function batchTimeoutMs(fileCount) {
166
+ return Math.min(12e4, 15e3 + fileCount * 1500);
167
+ }
168
+ var _goBatchScriptPath = null;
169
+ var _pyBatchScriptPath = null;
170
+ function batchPayload(files) {
171
+ return JSON.stringify(files.map((f) => ({ file: f.file, content: f.content })));
172
+ }
173
+ function collectBatch(stdout, lang) {
174
+ const out = /* @__PURE__ */ new Map();
175
+ for (const entry of parseParserBatchOutput(stdout, lang)) {
176
+ if (entry.error !== void 0) continue;
177
+ out.set(entry.file, {
178
+ file: entry.file,
179
+ lang,
180
+ symbols: toIndexSymbols(entry.symbols, entry.file, lang),
181
+ refs: entry.refs,
182
+ mtimeMs: Date.now()
183
+ });
184
+ }
185
+ return out;
186
+ }
187
+ async function runGoBatch(files, goBinary) {
188
+ if (files.length === 0) return /* @__PURE__ */ new Map();
189
+ const scriptPath = await privateScriptPath("ws-go-parse-", "batch.go", GO_BATCH_SCRIPT);
190
+ _goBatchScriptPath = scriptPath;
191
+ const result = await withSpawnGate(
192
+ () => runToolchainChild(
193
+ goBinary ?? resolveWin32Command("go"),
194
+ ["run", scriptPath],
195
+ batchPayload(files),
196
+ batchTimeoutMs(files.length),
197
+ goSpawnOptions(scriptPath)
198
+ )
199
+ );
200
+ if (result?.code !== 0 || !result.stdout.trim()) return /* @__PURE__ */ new Map();
201
+ return collectBatch(result.stdout, "go");
202
+ }
203
+ async function runPyBatch(files, pythonBinary) {
204
+ if (files.length === 0) return /* @__PURE__ */ new Map();
205
+ const scriptPath = await privateScriptPath("ws-py-parse-", "batch.py", PY_BATCH_SCRIPT);
206
+ _pyBatchScriptPath = scriptPath;
207
+ const result = await withSpawnGate(
208
+ () => runToolchainChild(
209
+ pythonBinary,
210
+ [scriptPath],
211
+ batchPayload(files),
212
+ batchTimeoutMs(files.length),
213
+ pySpawnOptions(scriptPath)
214
+ )
215
+ );
216
+ if (result?.code !== 0 || !result.stdout.trim()) return /* @__PURE__ */ new Map();
217
+ return collectBatch(result.stdout, "py");
218
+ }
219
+
220
+ // src/codebase-index/parser-dispatch.ts
221
+ async function parseFileContent(file, content, lang) {
222
+ const parsed = await dispatch(file, content, lang);
223
+ return withRelations(parsed, content, lang);
224
+ }
225
+ async function parseFilesContent(files) {
226
+ if (files.length === 0) return [];
227
+ const slots = files.map(() => ({ result: null }));
228
+ const batchingEnabled = process.env["WRONGSTACK_TOOLCHAIN_BATCH"] !== "0";
229
+ if (batchingEnabled) {
230
+ const goFiles = [];
231
+ const pyFiles = [];
232
+ files.forEach((f, index) => {
233
+ if (f.lang === "go") goFiles.push({ ...f, index });
234
+ else if (f.lang === "py") pyFiles.push({ ...f, index });
235
+ });
236
+ if (goFiles.length > 0) {
237
+ await applyBatchResults(slots, goFiles, (chunks) => runGoBatch(chunks), "go");
238
+ }
239
+ if (pyFiles.length > 0) {
240
+ const pyBinary = await resolvePythonBinary();
241
+ if (pyBinary) {
242
+ await applyBatchResults(slots, pyFiles, (chunks) => runPyBatch(chunks, pyBinary), "py");
243
+ }
244
+ }
245
+ }
246
+ const jobs = [];
247
+ for (let i = 0; i < files.length; i++) {
248
+ if (slots[i].result !== null) continue;
249
+ const { file, content, lang } = files[i];
250
+ const slot = slots[i];
251
+ jobs.push(
252
+ (async () => {
253
+ try {
254
+ slot.result = await parseFileContent(file, content, lang);
255
+ } catch (err) {
256
+ slot.error = err instanceof Error ? err.message : String(err);
257
+ }
258
+ })()
259
+ );
260
+ }
261
+ await Promise.all(jobs);
262
+ return slots;
263
+ }
264
+ async function applyBatchResults(slots, batchFiles, runBatch, lang) {
265
+ for (const chunk of chunkBatchFiles(batchFiles)) {
266
+ let byFile = null;
267
+ try {
268
+ byFile = await runBatch(chunk);
269
+ } catch {
270
+ byFile = null;
271
+ }
272
+ if (!byFile) continue;
273
+ for (const item of chunk) {
274
+ const parsed = byFile.get(item.file);
275
+ if (!parsed) continue;
276
+ slots[item.index] = { result: withRelations(parsed, item.content, lang) };
277
+ }
278
+ }
279
+ }
280
+ async function dispatch(file, content, lang) {
281
+ switch (lang) {
282
+ case "ts":
283
+ case "tsx":
284
+ case "js":
285
+ case "jsx": {
286
+ const { parseSymbols } = await import("./ts-parser-PML6QIH7.js");
287
+ return parseSymbols({ file, content, lang });
288
+ }
289
+ case "go": {
290
+ const { parseSymbols } = await import("./go-parser-LWV3L5V7.js");
291
+ return parseSymbols({ file, content, lang: "go" });
292
+ }
293
+ case "py": {
294
+ const { parseSymbols } = await import("./py-parser-B6D6RGH7.js");
295
+ return parseSymbols({ file, content, lang: "py" });
296
+ }
297
+ case "rs": {
298
+ const { parseSymbols } = await import("./rs-parser-L7SP4GWJ.js");
299
+ return parseSymbols({ file, content, lang: "rs" });
300
+ }
301
+ case "json": {
302
+ const { parseSymbols } = await import("./json-parser-PERV2JHX.js");
303
+ return parseSymbols({ file, content, lang: "json" });
304
+ }
305
+ case "yaml": {
306
+ const { parseSymbols } = await import("./yaml-parser-7BJN544B.js");
307
+ return parseSymbols({ file, content, lang: "yaml" });
308
+ }
309
+ // Phase 1: ten languages now route through the Tree-Sitter WASM
310
+ // universal parser (`tree-sitter-parser.ts`). The dispatch falls back to
311
+ // the regex extractor in `generic-parser.ts` whenever WASM loading fails
312
+ // or the parser returns zero symbols — preserving the indexable-file
313
+ // contract that "missing a parser must never mean skipping the file".
314
+ case "c":
315
+ case "cpp":
316
+ case "java":
317
+ case "csharp":
318
+ case "php":
319
+ case "ruby":
320
+ case "swift":
321
+ case "kotlin":
322
+ case "shell":
323
+ case "elixir": {
324
+ try {
325
+ const { parseSymbols: parseSymbols2 } = await import("./tree-sitter-parser-KU6JF3ZC.js");
326
+ const parsed = await parseSymbols2({ file, content, lang });
327
+ if (parsed.symbols.length > 0) return parsed;
328
+ } catch {
329
+ }
330
+ const { parseSymbols } = await import("./generic-parser-IVWLFKMR.js");
331
+ return parseSymbols({ file, content, lang });
332
+ }
333
+ default: {
334
+ const { parseSymbols } = await import("./generic-parser-IVWLFKMR.js");
335
+ return parseSymbols({ file, content, lang });
336
+ }
337
+ }
338
+ }
339
+ function withRelations(parsed, content, lang) {
340
+ let refs = parsed.refs ?? [];
341
+ if (refs.length === 0 && hasImportPatterns(lang)) {
342
+ refs = extractImports({ content, lang });
343
+ }
344
+ return { ...parsed, refs: refs.map((ref) => ref.lang ? ref : { ...ref, lang }) };
345
+ }
346
+
347
+ export {
348
+ parseFileContent,
349
+ parseFilesContent
350
+ };
351
+ //# sourceMappingURL=chunk-BJ5LXLKE.js.map
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-ZBMANLYH.js";
7
7
  import {
8
8
  enqueueReindex
9
- } from "./chunk-HYHE4VNA.js";
9
+ } from "./chunk-UMOP3VGK.js";
10
10
  import {
11
11
  isBinaryBuffer,
12
12
  safeResolveReal,
@@ -423,4 +423,4 @@ export {
423
423
  replaceTool,
424
424
  __resetRgDetectionForTests
425
425
  };
426
- //# sourceMappingURL=chunk-C6ZOXNXV.js.map
426
+ //# sourceMappingURL=chunk-CSS42GRP.js.map
@@ -1,4 +1,5 @@
1
1
  // src/codebase-index/generic-parser.ts
2
+ var NOT_STATEMENT = "(?!(?:return|new|throw|else|case|delete|goto|await|yield|sizeof|typeof)\\b)";
2
3
  var C_LIKE = [
3
4
  { re: /\b(?:class|struct|enum|interface|union)\s+([A-Za-z_]\w*)/g, kind: "class" },
4
5
  {
@@ -12,7 +13,10 @@ var C_LIKE = [
12
13
  // separates type from name. Generic types with internal spaces
13
14
  // (`Map<String, Integer> x;`) are no longer matched — tree-sitter is the
14
15
  // primary parser for C/C++ and this is only its WASM-less fallback.
15
- re: /\b(?:(?:public|private|protected|static|final|async|override|virtual|inline|export)\s+)?[\w:<>[\]*&]+\s+([A-Za-z_]\w*)\s*\([^;{]*\)\s*(?:const)?\s*[{;]/g,
16
+ re: new RegExp(
17
+ `\\b(?:(?:public|private|protected|static|final|async|override|virtual|inline|export)\\s+)?${NOT_STATEMENT}[\\w:<>[\\]*&]+\\s+([A-Za-z_]\\w*)\\s*\\([^;{]*\\)\\s*(?:const)?\\s*[{;]`,
18
+ "g"
19
+ ),
16
20
  kind: "function"
17
21
  },
18
22
  { re: /\b(?:namespace)\s+([A-Za-z_]\w*)/g, kind: "namespace" }
@@ -21,7 +25,8 @@ var LANG_PATTERNS = {
21
25
  py: [
22
26
  { re: /^(?:async\s+)?def\s+([A-Za-z_]\w*)/gm, kind: "function" },
23
27
  { re: /^class\s+([A-Za-z_]\w*)/gm, kind: "class" },
24
- { re: /^([A-Za-z_]\w*)\s*=/gm, kind: "var" }
28
+ // `(?!=)`: a top-level comparison (`x == y`) is not an assignment.
29
+ { re: /^([A-Za-z_]\w*)\s*=(?!=)/gm, kind: "var" }
25
30
  ],
26
31
  go: [
27
32
  { re: /^func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)\s*\(/gm, kind: "function" },
@@ -47,7 +52,10 @@ var LANG_PATTERNS = {
47
52
  // `(?:…|\s)+\s*[\w.<>,[\]\s]+\s+` let three quantifiers compete for the
48
53
  // same whitespace (800 bytes of padding measured at 42 s). Whitespace
49
54
  // now has exactly one owner per position.
50
- re: /\b(?:(?:public|private|protected|static|final|abstract|synchronized|native|default)\s+)*[\w.$,<>[\]]+\s+([A-Za-z_]\w*)\s*\(/g,
55
+ re: new RegExp(
56
+ `\\b(?:(?:public|private|protected|static|final|abstract|synchronized|native|default)\\s+)*${NOT_STATEMENT}[\\w.$,<>[\\]]+\\s+([A-Za-z_]\\w*)\\s*\\(`,
57
+ "g"
58
+ ),
51
59
  kind: "method"
52
60
  }
53
61
  ],
@@ -56,7 +64,10 @@ var LANG_PATTERNS = {
56
64
  { re: /\bnamespace\s+([A-Za-z_.\w]+)/g, kind: "namespace" },
57
65
  {
58
66
  // H-10: see java above.
59
- re: /\b(?:(?:public|private|protected|internal|static|async|override|virtual)\s+)*[\w.$,<>[\]]+\s+([A-Za-z_]\w*)\s*\(/g,
67
+ re: new RegExp(
68
+ `\\b(?:(?:public|private|protected|internal|static|async|override|virtual)\\s+)*${NOT_STATEMENT}[\\w.$,<>[\\]]+\\s+([A-Za-z_]\\w*)\\s*\\(`,
69
+ "g"
70
+ ),
60
71
  kind: "method"
61
72
  }
62
73
  ],
@@ -97,7 +108,9 @@ var LANG_PATTERNS = {
97
108
  }
98
109
  ],
99
110
  md: [{ re: /^(#{1,6})\s+(.+)$/gm, kind: "namespace" }],
100
- toml: [{ re: /^\[([^\]]+)\]/gm, kind: "namespace" }],
111
+ // `[table]` and `[[array.of.tables]]` — the old `^\[([^\]]+)\]` captured
112
+ // `[bin` for `[[bin]]`.
113
+ toml: [{ re: /^\[\[?\s*([^[\]\s][^[\]]*?)\s*\]\]?/gm, kind: "namespace" }],
101
114
  html: [
102
115
  { re: /\bid\s*=\s*["']([^"']+)["']/gi, kind: "property" },
103
116
  { re: /<(?:script|template|style)\b/gi, kind: "namespace" }
@@ -231,6 +244,24 @@ var KEYWORDS = /* @__PURE__ */ new Set([
231
244
  "await",
232
245
  "yield"
233
246
  ]);
247
+ function maskMarkdownFences(content) {
248
+ const lines = content.split("\n");
249
+ let fence = null;
250
+ for (let i = 0; i < lines.length; i++) {
251
+ const line = lines[i] ?? "";
252
+ const marker = /^\s{0,3}(`{3,}|~{3,})/.exec(line)?.[1];
253
+ if (fence === null) {
254
+ if (marker) fence = marker;
255
+ continue;
256
+ }
257
+ if (marker && marker[0] === fence[0] && marker.length >= fence.length) {
258
+ fence = null;
259
+ continue;
260
+ }
261
+ lines[i] = line.replace(/[^\r]/g, " ");
262
+ }
263
+ return lines.join("\n");
264
+ }
234
265
  function patternsFor(lang) {
235
266
  return LANG_PATTERNS[lang] ?? LANG_PATTERNS.other ?? [];
236
267
  }
@@ -273,7 +304,8 @@ function parseGeneric(opts) {
273
304
  if (!opts.content || looksBinary(opts.content)) {
274
305
  return { file, lang, symbols: [], mtimeMs };
275
306
  }
276
- const content = opts.content.length > GENERIC_MAX_FILE_CHARS ? opts.content.slice(0, GENERIC_MAX_FILE_CHARS) : opts.content;
307
+ const bounded = opts.content.length > GENERIC_MAX_FILE_CHARS ? opts.content.slice(0, GENERIC_MAX_FILE_CHARS) : opts.content;
308
+ const content = lang === "md" ? maskMarkdownFences(bounded) : bounded;
277
309
  const patterns = patternsFor(lang);
278
310
  const symbols = [];
279
311
  const seen = /* @__PURE__ */ new Set();
@@ -290,7 +322,8 @@ function parseGeneric(opts) {
290
322
  if (lang === "md" && match[2]) name = match[2].trim();
291
323
  if (!name || name.length > 200) continue;
292
324
  name = name.replace(/^#+\s*/, "").replace(/["'`]/g, "");
293
- if (!name || KEYWORDS.has(name.toLowerCase())) continue;
325
+ if (!name) continue;
326
+ if (lang !== "md" && lang !== "toml" && KEYWORDS.has(name)) continue;
294
327
  if (!/^[A-Za-z_#.@/\w][\w.\-:/#!?]*$/.test(name) && lang !== "md" && lang !== "toml") {
295
328
  continue;
296
329
  }
@@ -329,4 +362,4 @@ export {
329
362
  parseGeneric,
330
363
  parseSymbols
331
364
  };
332
- //# sourceMappingURL=chunk-SKRMUHTU.js.map
365
+ //# sourceMappingURL=chunk-HSLDY55L.js.map