@wrongstack/tools 1.0.10 → 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.
- package/dist/builtin.js +17 -17
- package/dist/{chunk-6I6RXQFG.js → chunk-2BCRQAIW.js} +9 -9
- package/dist/{chunk-XRNN44QY.js → chunk-2IRHFHZY.js} +235 -71
- package/dist/{chunk-5RBUYFRV.js → chunk-4IMNVQRB.js} +8 -2
- package/dist/{chunk-NEYUPZL6.js → chunk-6D3UIQMF.js} +651 -303
- package/dist/chunk-BJ5LXLKE.js +351 -0
- package/dist/{chunk-C6ZOXNXV.js → chunk-CSS42GRP.js} +2 -2
- package/dist/{chunk-SKRMUHTU.js → chunk-HSLDY55L.js} +41 -8
- package/dist/{chunk-ENE22I5W.js → chunk-K37AKCTN.js} +884 -362
- package/dist/{chunk-V25Q6TQ7.js → chunk-K3VX6V5P.js} +3 -3
- package/dist/chunk-OIFY4XNP.js +855 -0
- package/dist/{chunk-OUERRFEM.js → chunk-OMQDKZOT.js} +17 -8
- package/dist/{chunk-7GOE2ZTZ.js → chunk-OMWC2OGT.js} +2 -2
- package/dist/{chunk-IE4KDAOB.js → chunk-OYQE2UNT.js} +3 -3
- package/dist/chunk-R3HR3QI3.js +97 -0
- package/dist/{chunk-XPVYZ2S6.js → chunk-RYLMSGR5.js} +2 -2
- package/dist/{chunk-HYHE4VNA.js → chunk-UMOP3VGK.js} +79 -45
- package/dist/{chunk-FVSMTEO3.js → chunk-VMNWQI4V.js} +2 -2
- package/dist/{chunk-2UVAIS5O.js → chunk-YPSVPCIE.js} +2 -2
- package/dist/{chunk-PWZUHZP7.js → chunk-Z77XMU3U.js} +2 -2
- package/dist/codebase-index/ast-invariant-engine.d.ts +19 -2
- package/dist/codebase-index/atlas-projection.d.ts +19 -0
- package/dist/codebase-index/background-indexer.d.ts +14 -0
- package/dist/codebase-index/circuit-breaker.d.ts +7 -0
- package/dist/codebase-index/codebase-ast-replace-tool.d.ts +1 -1
- package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +6 -0
- package/dist/codebase-index/codebase-invariant-check-tool.d.ts +2 -0
- package/dist/codebase-index/codebase-targeted-test-tool.d.ts +26 -0
- package/dist/codebase-index/dead-code-scan.d.ts +4 -0
- package/dist/codebase-index/go-parser.d.ts +23 -3
- package/dist/codebase-index/graph-rank-pass.d.ts +10 -0
- package/dist/codebase-index/graph-rank.d.ts +8 -0
- package/dist/codebase-index/index.d.ts +1 -1
- package/dist/codebase-index/index.js +9 -9
- package/dist/codebase-index/lsp-kind.d.ts +3 -1
- package/dist/codebase-index/module-resolver.d.ts +21 -1
- package/dist/codebase-index/parser-batch.d.ts +6 -8
- package/dist/codebase-index/parser-output.d.ts +5 -1
- package/dist/codebase-index/parser-worker-script.js +4 -4
- package/dist/codebase-index/project-server-framing.d.ts +1 -17
- package/dist/codebase-index/project-server-watcher.d.ts +6 -0
- package/dist/codebase-index/project-server.js +72 -26
- package/dist/codebase-index/py-parser.d.ts +4 -4
- package/dist/codebase-index/rs-parser.d.ts +7 -0
- package/dist/codebase-index/toolchain-scripts.d.ts +64 -0
- package/dist/codebase-index/tree-sitter/queries.d.ts +14 -0
- package/dist/codebase-index/tree-sitter/util.d.ts +6 -1
- package/dist/codebase-index/tree-sitter-parser.d.ts +7 -0
- package/dist/codebase-index/worker.js +23 -16
- package/dist/codebase-index/writer-refs.d.ts +17 -2
- package/dist/codebase-index/writer-search-helpers.d.ts +9 -0
- package/dist/codebase-index/writer.d.ts +20 -1
- package/dist/edit.js +8 -8
- package/dist/{generic-parser-N2PLGBC2.js → generic-parser-IVWLFKMR.js} +2 -2
- package/dist/go-parser-LWV3L5V7.js +197 -0
- package/dist/index.js +19 -19
- package/dist/json-parser-PERV2JHX.js +204 -0
- package/dist/pack.js +18 -18
- package/dist/parser-dispatch-ZSWCQB6M.js +14 -0
- package/dist/patch.js +8 -8
- package/dist/{py-parser-4PFZYAJ7.js → py-parser-B6D6RGH7.js} +4 -4
- package/dist/read.js +8 -8
- package/dist/replace.js +8 -8
- package/dist/rs-parser-L7SP4GWJ.js +182 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +1 -1
- package/dist/tool-tier.js +19 -19
- package/dist/{tree-sitter-parser-GILYQLS4.js → tree-sitter-parser-KU6JF3ZC.js} +6 -4
- package/dist/{ts-parser-7W26YB26.js → ts-parser-PML6QIH7.js} +55 -23
- package/dist/typecheck.js +1 -1
- package/dist/write.js +8 -8
- package/dist/{yaml-parser-DFBC5FWH.js → yaml-parser-7BJN544B.js} +41 -6
- package/package.json +5 -5
- package/dist/chunk-4CE3RKEP.js +0 -390
- package/dist/chunk-KHUCKLOR.js +0 -899
- package/dist/chunk-ZKC5UNGD.js +0 -167
- package/dist/go-parser-Z4H6SR3R.js +0 -474
- package/dist/json-parser-IJD77VL4.js +0 -256
- package/dist/parser-dispatch-WG4DNBHH.js +0 -14
- 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-
|
|
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-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
|
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-
|
|
365
|
+
//# sourceMappingURL=chunk-HSLDY55L.js.map
|