@wrongstack/tools 0.313.0 → 0.316.1
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/_edit-match.d.ts +3 -2
- package/dist/_output-spool.d.ts +4 -3
- package/dist/_shell-pick.d.ts +2 -1
- package/dist/_spawn-stream.d.ts +2 -1
- package/dist/_syntax-check.d.ts +2 -1
- package/dist/audit.js +10 -4055
- package/dist/bash-kill-guard.d.ts +3 -6
- package/dist/bash.js +9 -2308
- package/dist/batch-tool-use.js +2 -187
- package/dist/browser/index.js +25 -1339
- package/dist/browser/network-guard-proxy.d.ts +2 -1
- package/dist/builtin.js +69 -33949
- package/dist/chunk-22B7GE5T.js +260 -0
- package/dist/chunk-2VSZC6QM.js +113 -0
- package/dist/chunk-3PVYQFRQ.js +472 -0
- package/dist/chunk-42BHI7TN.js +337 -0
- package/dist/chunk-4BHUSMNL.js +104 -0
- package/dist/chunk-4I4LWFOO.js +431 -0
- package/dist/chunk-4UESMQDP.js +122 -0
- package/dist/chunk-553IQUMO.js +478 -0
- package/dist/chunk-5H4GSJAI.js +223 -0
- package/dist/chunk-6RNIFLG4.js +305 -0
- package/dist/chunk-7EY5DCRO.js +434 -0
- package/dist/chunk-A6BRWIXN.js +317 -0
- package/dist/chunk-AHHDWNXC.js +200 -0
- package/dist/chunk-BSLVR56S.js +199 -0
- package/dist/chunk-BTSFTGIL.js +7 -0
- package/dist/chunk-D33S4RQG.js +222 -0
- package/dist/chunk-DA4KNE2H.js +4412 -0
- package/dist/chunk-DR7JOQTC.js +520 -0
- package/dist/chunk-EEOFQDT6.js +898 -0
- package/dist/chunk-EJWSCQ6D.js +137 -0
- package/dist/chunk-EMRGN4KM.js +170 -0
- package/dist/chunk-FQZOHLG3.js +89 -0
- package/dist/chunk-GOIZNNOA.js +221 -0
- package/dist/chunk-HFXSNKCV.js +196 -0
- package/dist/chunk-HYX2TZ7O.js +1272 -0
- package/dist/chunk-I64BS3VC.js +15 -0
- package/dist/chunk-IVWV2UM6.js +955 -0
- package/dist/chunk-IXMNTNW5.js +238 -0
- package/dist/chunk-IYK7XGDZ.js +892 -0
- package/dist/chunk-J5SKD6LN.js +235 -0
- package/dist/chunk-JNNVRHMV.js +2111 -0
- package/dist/chunk-JOHXDF3D.js +295 -0
- package/dist/chunk-JRJJX3L5.js +424 -0
- package/dist/chunk-K3WNSHUF.js +1371 -0
- package/dist/chunk-L25CVUVR.js +2830 -0
- package/dist/chunk-LIJQMYYX.js +59 -0
- package/dist/chunk-LWKUTMD5.js +197 -0
- package/dist/chunk-MQX2KXVW.js +54 -0
- package/dist/chunk-MZZN7VCD.js +359 -0
- package/dist/chunk-NBDZMMG2.js +169 -0
- package/dist/chunk-NKJW5GFO.js +366 -0
- package/dist/chunk-NKNOBUBU.js +522 -0
- package/dist/chunk-O4MBV4AX.js +134 -0
- package/dist/chunk-OUBDL3WH.js +3515 -0
- package/dist/chunk-PQKK5JH7.js +101 -0
- package/dist/chunk-PY2IOS7C.js +1000 -0
- package/dist/chunk-Q5JPPCZC.js +12 -0
- package/dist/chunk-QBV725YG.js +128 -0
- package/dist/chunk-QZQSPUBF.js +315 -0
- package/dist/chunk-RGISBZBD.js +231 -0
- package/dist/chunk-RJZQWEMS.js +84 -0
- package/dist/chunk-RXISBFR5.js +315 -0
- package/dist/chunk-S5CCLZL3.js +99 -0
- package/dist/chunk-SDLVH5RZ.js +178 -0
- package/dist/chunk-T2F4S7U4.js +1723 -0
- package/dist/chunk-TEBQ4VPZ.js +163 -0
- package/dist/chunk-U4D5S3VQ.js +21 -0
- package/dist/chunk-U4VAATKP.js +193 -0
- package/dist/chunk-UCYQTZ7F.js +113 -0
- package/dist/chunk-UKU2ZX4C.js +203 -0
- package/dist/chunk-UNSKG6DC.js +159 -0
- package/dist/chunk-V43EQ6VR.js +68 -0
- package/dist/chunk-VB3MJGCV.js +610 -0
- package/dist/chunk-VFKPWSOX.js +154 -0
- package/dist/chunk-VJNHFZ7J.js +190 -0
- package/dist/chunk-VXECAJJ7.js +1091 -0
- package/dist/chunk-WHIIIREL.js +223 -0
- package/dist/chunk-Z6DAKQ3U.js +1 -0
- package/dist/chunk-ZJQ4IGXK.js +474 -0
- package/dist/chunk-ZLTFLC25.js +385 -0
- package/dist/circuit-breaker.js +3 -191
- package/dist/codebase-index/ast-invariant-engine.d.ts +5 -4
- package/dist/codebase-index/binary-frame.d.ts +0 -2
- package/dist/codebase-index/bm25.d.ts +1 -1
- package/dist/codebase-index/circuit-breaker.d.ts +2 -1
- package/dist/codebase-index/codebase-ast-replace-tool.d.ts +3 -2
- package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +4 -3
- package/dist/codebase-index/codebase-invariant-check-tool.d.ts +3 -2
- package/dist/codebase-index/codebase-repo-map-tool.d.ts +3 -2
- package/dist/codebase-index/codebase-skeleton-tool.d.ts +3 -2
- package/dist/codebase-index/codebase-targeted-test-tool.d.ts +3 -2
- package/dist/codebase-index/content-hash.d.ts +0 -2
- package/dist/codebase-index/import-extractor.d.ts +0 -13
- package/dist/codebase-index/index-service.d.ts +1 -1
- package/dist/codebase-index/index.js +84 -13688
- package/dist/codebase-index/languages.d.ts +2 -1
- package/dist/codebase-index/module-roots.d.ts +3 -2
- package/dist/codebase-index/parser-batch.d.ts +0 -5
- package/dist/codebase-index/parser-dispatch.d.ts +2 -1
- package/dist/codebase-index/parser-output.d.ts +4 -3
- package/dist/codebase-index/parser-worker-pool.d.ts +0 -2
- package/dist/codebase-index/parser-worker-script.d.ts +1 -16
- package/dist/codebase-index/parser-worker-script.js +8 -3995
- package/dist/codebase-index/project-server-client-state.d.ts +2 -2
- package/dist/codebase-index/project-server-endpoint.d.ts +0 -15
- package/dist/codebase-index/project-server.js +60 -8548
- package/dist/codebase-index/tree-sitter/visitor.d.ts +2 -1
- package/dist/codebase-index/tree-sitter-parser.d.ts +0 -2
- package/dist/codebase-index/ts-parser.d.ts +1 -1
- package/dist/codebase-index/vector-search.d.ts +2 -1
- package/dist/codebase-index/wal-maintenance.d.ts +3 -2
- package/dist/codebase-index/worker.js +20 -8416
- package/dist/codebase-index/writer-admin.d.ts +0 -1
- package/dist/codebase-index/writer-search.d.ts +0 -9
- package/dist/design.js +2 -299
- package/dist/diff.js +4 -256
- package/dist/document.js +4 -222
- package/dist/e2e.js +5 -476
- package/dist/edit.js +14 -10200
- package/dist/exec.js +16 -3131
- package/dist/fetch.js +8 -398
- package/dist/format.js +10 -3750
- package/dist/generic-parser-VUXDIAOZ.js +13 -0
- package/dist/git.js +4 -380
- package/dist/glob.js +6 -280
- package/dist/go-parser-JXYKJHRC.js +469 -0
- package/dist/grep.js +7 -604
- package/dist/index.js +318 -35387
- package/dist/install.js +10 -4091
- package/dist/json-parser-IBHZ4BZC.js +213 -0
- package/dist/json.js +4 -665
- package/dist/kanban-contract-actions.d.ts +1 -1
- package/dist/kanban-detail-actions.d.ts +2 -1
- package/dist/kanban-presence.d.ts +2 -1
- package/dist/kanban-serializer.d.ts +0 -8
- package/dist/kanban-split-task-handler.d.ts +2 -2
- package/dist/kanban-tool-types.d.ts +2 -1
- package/dist/kanban.js +3 -2096
- package/dist/languages/diagnostics.d.ts +2 -1
- package/dist/languages/index.js +23 -4664
- package/dist/languages/legacy-bridge.d.ts +3 -2
- package/dist/languages/types.d.ts +2 -1
- package/dist/legacy-bridge-7M6QLUQN.js +18 -0
- package/dist/lint.js +10 -3706
- package/dist/logs.js +4 -287
- package/dist/memory.js +6 -215
- package/dist/mode.js +3 -99
- package/dist/outdated.js +4 -5170
- package/dist/pack.js +65 -33897
- package/dist/parser-dispatch-QH4XPGG6.js +14 -0
- package/dist/patch.js +13 -9935
- package/dist/plan.js +5 -3286
- package/dist/process-registry.js +8 -651
- package/dist/ps-slash.js +12 -1439
- package/dist/pwsh.d.ts +0 -1
- package/dist/py-parser-IS4HKYMF.js +16 -0
- package/dist/read.js +13 -9816
- package/dist/replace.js +15 -10014
- package/dist/rs-parser-XHUUO2KZ.js +81 -0
- package/dist/scaffold.js +4 -253
- package/dist/search.js +5 -585
- package/dist/session-kanban-sync.d.ts +0 -6
- package/dist/session-kanban.js +30 -972
- package/dist/skill.js +2 -215
- package/dist/spawn-background.d.ts +1 -1
- package/dist/task.js +5 -3410
- package/dist/test.js +10 -3773
- package/dist/todo.js +4 -2891
- package/dist/tool-help.js +3 -123
- package/dist/tool-search.js +3 -79
- package/dist/tool-tier.js +68 -33984
- package/dist/tool-use.js +2 -93
- package/dist/tree-sitter-parser-AIERW3YI.js +15 -0
- package/dist/tree.js +4 -288
- package/dist/ts-parser-RCTYKSVI.js +232 -0
- package/dist/typecheck.js +10 -3753
- package/dist/win32.js +6 -60
- package/dist/write.js +14 -9882
- package/dist/yaml-parser-4SAXV3PL.js +157 -0
- package/package.json +5 -5
|
@@ -0,0 +1,898 @@
|
|
|
1
|
+
// src/codebase-index/tree-sitter-parser.ts
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
// src/codebase-index/tree-sitter/queries.ts
|
|
6
|
+
function parseGroupedUse(text) {
|
|
7
|
+
const open = text.indexOf("{");
|
|
8
|
+
const close = text.lastIndexOf("}");
|
|
9
|
+
if (open < 0 || close <= open) return null;
|
|
10
|
+
const prefix = text.slice(0, open).replace(/[\\/]+$/, "");
|
|
11
|
+
const out = [];
|
|
12
|
+
for (const rawMember of text.slice(open + 1, close).split(",")) {
|
|
13
|
+
let member = rawMember.trim();
|
|
14
|
+
if (!member) continue;
|
|
15
|
+
member = member.replace(
|
|
16
|
+
/^(static|final|type|class|struct|enum|protocol|var|func|let|typealias|function|const)\s+/i,
|
|
17
|
+
""
|
|
18
|
+
).trim();
|
|
19
|
+
if (!member) continue;
|
|
20
|
+
const aliasMatch = /\s+as\s+([A-Za-z_]\w*)\s*$/i.exec(member);
|
|
21
|
+
if (aliasMatch) member = member.slice(0, aliasMatch.index).trim();
|
|
22
|
+
if (!member) continue;
|
|
23
|
+
const module = prefix ? `${prefix}\\${member}` : member;
|
|
24
|
+
const toName = member.split(/[\\/]/).filter(Boolean).pop();
|
|
25
|
+
if (toName) out.push({ toName, callType: "import", module });
|
|
26
|
+
}
|
|
27
|
+
return out.length ? out : null;
|
|
28
|
+
}
|
|
29
|
+
function importFromText(prefixes) {
|
|
30
|
+
return (node) => {
|
|
31
|
+
let text = node.text.replace(/\s+/g, " ").trim();
|
|
32
|
+
for (const prefix of prefixes) {
|
|
33
|
+
if (text.startsWith(prefix)) text = text.slice(prefix.length).trim();
|
|
34
|
+
}
|
|
35
|
+
text = text.replace(
|
|
36
|
+
/^(static|final|type|class|struct|enum|protocol|var|func|let|typealias|function|const)\s+/i,
|
|
37
|
+
""
|
|
38
|
+
).trim();
|
|
39
|
+
if (text.includes("{")) return parseGroupedUse(text);
|
|
40
|
+
if (text.includes(",") && !text.includes("<") && !text.includes("=")) {
|
|
41
|
+
const out = [];
|
|
42
|
+
for (const clause of text.split(",")) {
|
|
43
|
+
const one = oneImportClause(clause.trim());
|
|
44
|
+
if (one) out.push(one);
|
|
45
|
+
}
|
|
46
|
+
return out.length ? out : null;
|
|
47
|
+
}
|
|
48
|
+
const single = oneImportClause(text);
|
|
49
|
+
return single ? [single] : null;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function oneImportClause(rawClause) {
|
|
53
|
+
let text = rawClause;
|
|
54
|
+
text = text.replace(
|
|
55
|
+
/^(static|final|type|class|struct|enum|protocol|var|func|let|typealias|function|const)\s+/i,
|
|
56
|
+
""
|
|
57
|
+
).trim();
|
|
58
|
+
text = text.replace(/[;}]+$/g, "").trim();
|
|
59
|
+
const aliasMatch = /\s+as\s+([A-Za-z_]\w*)\s*$/i.exec(text);
|
|
60
|
+
if (aliasMatch) text = text.slice(0, aliasMatch.index).trim();
|
|
61
|
+
const eqMatch = /^([A-Za-z_]\w*)\s*=\s*(.+)$/.exec(text);
|
|
62
|
+
if (eqMatch) text = eqMatch[2].trim();
|
|
63
|
+
if (!text) return null;
|
|
64
|
+
if (text.endsWith("*")) text = text.slice(0, -1).replace(/[.]$/, "");
|
|
65
|
+
if (!text) return null;
|
|
66
|
+
const module = text;
|
|
67
|
+
const toName = module.split(/[.\\/]/).filter(Boolean).pop()?.replace(/<.*>$/s, "");
|
|
68
|
+
if (!toName) return null;
|
|
69
|
+
return { toName, callType: "import", module };
|
|
70
|
+
}
|
|
71
|
+
var heritageExtractor = (node) => {
|
|
72
|
+
const out = [];
|
|
73
|
+
const SKIP_SUBTREES = /* @__PURE__ */ new Set([
|
|
74
|
+
"type_arguments",
|
|
75
|
+
"type_argument_list",
|
|
76
|
+
// tree-sitter-cpp names its argument subtree template_argument_list —
|
|
77
|
+
// verified AST: (base_class_clause (template_type name:
|
|
78
|
+
// (type_identifier) arguments: (template_argument_list
|
|
79
|
+
// (type_descriptor type: (type_identifier))))). Without this entry
|
|
80
|
+
// `class D : Base<Foo>` recurses into the descriptor and emits Foo as a
|
|
81
|
+
// phantom inherit ref.
|
|
82
|
+
"template_argument_list",
|
|
83
|
+
"type_parameter_list",
|
|
84
|
+
"type_projection",
|
|
85
|
+
"value_arguments"
|
|
86
|
+
]);
|
|
87
|
+
const collect = (current, depth) => {
|
|
88
|
+
if (depth > 4) return;
|
|
89
|
+
for (let i = 0; i < current.namedChildCount; i++) {
|
|
90
|
+
const child = current.namedChild(i);
|
|
91
|
+
if (!child) continue;
|
|
92
|
+
if (SKIP_SUBTREES.has(child.type)) continue;
|
|
93
|
+
if (child.type === "type_identifier" || child.type === "identifier" || child.type === "named_type" || child.type === "type" || // PHP heritage carries `name`; Ruby a `constant`.
|
|
94
|
+
child.type === "constant" || child.type === "name") {
|
|
95
|
+
const name = child.type === "named_type" ? leafSegment(child.text) : child.text;
|
|
96
|
+
if (name) out.push({ toName: name });
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (child.type === "generic_type" || child.type === "generic_name") {
|
|
100
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
101
|
+
const inner = child.namedChild(j);
|
|
102
|
+
if (inner && !SKIP_SUBTREES.has(inner.type) && (inner.type === "type_identifier" || inner.type === "identifier" || inner.type === "name")) {
|
|
103
|
+
out.push({ toName: inner.text });
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (child.type === "qualified_name" || child.type === "scoped_type_identifier" || child.type === "user_type" || child.type === "scope_resolution") {
|
|
110
|
+
const leaf = heritageLeaf(child, 0);
|
|
111
|
+
if (leaf) out.push({ toName: leaf });
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
collect(child, depth + 1);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
collect(node, 0);
|
|
118
|
+
return out;
|
|
119
|
+
};
|
|
120
|
+
function heritageLeaf(node, depth) {
|
|
121
|
+
if (depth > 6) return null;
|
|
122
|
+
const named = node.childForFieldName("name");
|
|
123
|
+
if (named) {
|
|
124
|
+
if (named.type === "scoped_type_identifier" || named.type === "qualified_name" || named.type === "scope_resolution" || named.type === "user_type") {
|
|
125
|
+
return heritageLeaf(named, depth + 1);
|
|
126
|
+
}
|
|
127
|
+
return named.text;
|
|
128
|
+
}
|
|
129
|
+
const children = [];
|
|
130
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
131
|
+
const c = node.namedChild(i);
|
|
132
|
+
if (c) children.push(c);
|
|
133
|
+
}
|
|
134
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
135
|
+
const c = children[i];
|
|
136
|
+
if (c.type === "type_arguments" || c.type === "type_argument_list" || // cpp: (template_type arguments: (template_argument_list …)) — the
|
|
137
|
+
// descriptor's type_identifier inside it is never the declared base.
|
|
138
|
+
c.type === "template_argument_list" || c.type === "type_parameter_list" || c.type === "type_projection" || c.type === "value_arguments") {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (c.type === "type_identifier" || c.type === "identifier" || c.type === "constant" || c.type === "name") {
|
|
142
|
+
return c.text;
|
|
143
|
+
}
|
|
144
|
+
if (c.type === "scoped_type_identifier" || c.type === "qualified_name" || c.type === "scope_resolution" || c.type === "user_type") {
|
|
145
|
+
return heritageLeaf(c, depth + 1);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return leafSegment(
|
|
149
|
+
node.text.replace(/\\/g, ".").replace(/::/g, ".").replace(/<[^<>]*>$/, "")
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
function leafSegment(text) {
|
|
153
|
+
return text.split(".").filter(Boolean).pop() ?? text;
|
|
154
|
+
}
|
|
155
|
+
var cCallExtractor = (node) => {
|
|
156
|
+
const fn = node.childForFieldName("function");
|
|
157
|
+
if (!fn) return null;
|
|
158
|
+
if (fn.type === "field_expression") {
|
|
159
|
+
const field = fn.childForFieldName("field");
|
|
160
|
+
if (field) return [{ toName: field.text, callType: "call" }];
|
|
161
|
+
const seg = fn.text.split("->").filter(Boolean).pop();
|
|
162
|
+
if (seg) return [{ toName: leafSegment(seg.split(".")[0] ?? seg), callType: "call" }];
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
if (fn.type === "qualified_identifier") {
|
|
166
|
+
const name = fn.childForFieldName("name");
|
|
167
|
+
if (name) return [{ toName: name.text, callType: "call" }];
|
|
168
|
+
const seg = fn.text.split("::").filter(Boolean).pop();
|
|
169
|
+
if (seg) return [{ toName: seg.split(/[<(]/)[0].trim(), callType: "call" }];
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
return [{ toName: fn.text.split(/[<(]/)[0].trim(), callType: "call" }];
|
|
173
|
+
};
|
|
174
|
+
var rubyCallExtractor = (node) => {
|
|
175
|
+
const emissions = [];
|
|
176
|
+
const method = node.childForFieldName("method");
|
|
177
|
+
if (method) {
|
|
178
|
+
const name = method.text;
|
|
179
|
+
if (name && !name.includes(" ")) emissions.push({ toName: name, callType: "call" });
|
|
180
|
+
if (name === "require" || name === "require_relative") {
|
|
181
|
+
const args = node.childForFieldName("arguments");
|
|
182
|
+
const first = args?.namedChild(0);
|
|
183
|
+
if (first) {
|
|
184
|
+
const raw = first.text.replace(/^['"]|['"]$/g, "");
|
|
185
|
+
const toName = raw.split("/").filter(Boolean).pop();
|
|
186
|
+
if (toName) emissions.push({ toName, callType: "import", module: raw });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return emissions;
|
|
191
|
+
};
|
|
192
|
+
var firstIdentifierCallExtractor = (node) => {
|
|
193
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
194
|
+
const child = node.namedChild(i);
|
|
195
|
+
if (child && (child.type === "simple_identifier" || child.type === "identifier")) {
|
|
196
|
+
return [{ toName: child.text, callType: "call" }];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const first = node.namedChild(0);
|
|
200
|
+
if (!first) return null;
|
|
201
|
+
const leaf = leafSegment(first.text.split(/[<(]/)[0] ?? first.text);
|
|
202
|
+
if (!leaf) return null;
|
|
203
|
+
return [{ toName: leaf, callType: "call" }];
|
|
204
|
+
};
|
|
205
|
+
var cIncludeExtractor = (node) => {
|
|
206
|
+
const raw = node.text.replace(/^#\s*include\s*/i, "").trim();
|
|
207
|
+
const module = raw.replace(/^["'<]|["'>]$/g, "");
|
|
208
|
+
if (!module) return null;
|
|
209
|
+
const toName = module.split("/").pop()?.replace(/\.h$/, "");
|
|
210
|
+
if (!toName) return null;
|
|
211
|
+
return [{ toName, callType: "import", module }];
|
|
212
|
+
};
|
|
213
|
+
var phpConstructorExtractor = (node) => {
|
|
214
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
215
|
+
const child = node.namedChild(i);
|
|
216
|
+
if (child && (child.type === "qualified_name" || child.type === "name")) {
|
|
217
|
+
const leaf = child.text.split(/[\\]/).filter(Boolean).pop();
|
|
218
|
+
if (leaf) return [{ toName: leaf, callType: "call" }];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
};
|
|
223
|
+
var DEFAULT_QUERIES = {
|
|
224
|
+
declKinds: {}
|
|
225
|
+
};
|
|
226
|
+
var LANG_QUERIES = {
|
|
227
|
+
// ─── C family ──────────────────────────────────────────────────────────────
|
|
228
|
+
c: {
|
|
229
|
+
declKinds: {
|
|
230
|
+
function_definition: "function",
|
|
231
|
+
declaration: "function",
|
|
232
|
+
// K&R-style `int foo(...)` ambiguous w/ local var; the visitor prefers the function branch when the declarator field is present
|
|
233
|
+
struct_specifier: "struct",
|
|
234
|
+
union_specifier: "struct",
|
|
235
|
+
enum_specifier: "enum",
|
|
236
|
+
type_definition: "type",
|
|
237
|
+
// `typedef … X;`
|
|
238
|
+
preproc_def: "const"
|
|
239
|
+
// `#define NAME …`
|
|
240
|
+
},
|
|
241
|
+
nameField: {
|
|
242
|
+
function_definition: "declarator",
|
|
243
|
+
declaration: "declarator",
|
|
244
|
+
struct_specifier: "name",
|
|
245
|
+
enum_specifier: "name",
|
|
246
|
+
type_definition: "declarator",
|
|
247
|
+
preproc_def: "name"
|
|
248
|
+
},
|
|
249
|
+
scopeNodes: /* @__PURE__ */ new Set([
|
|
250
|
+
"translation_unit",
|
|
251
|
+
"function_definition",
|
|
252
|
+
"struct_specifier",
|
|
253
|
+
"union_specifier",
|
|
254
|
+
"enum_specifier"
|
|
255
|
+
]),
|
|
256
|
+
refRules: {
|
|
257
|
+
// `obj->run()` and `Cls::stat()` carry structured function fields —
|
|
258
|
+
// cCallExtractor handles all three AST shapes.
|
|
259
|
+
call_expression: { callType: "call", nameExtractor: cCallExtractor },
|
|
260
|
+
preproc_include: { callType: "import", nameExtractor: cIncludeExtractor }
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
cpp: {
|
|
264
|
+
declKinds: {
|
|
265
|
+
function_definition: "function",
|
|
266
|
+
template_declaration: "function",
|
|
267
|
+
// `template<typename T> …`
|
|
268
|
+
class_specifier: "class",
|
|
269
|
+
struct_specifier: "struct",
|
|
270
|
+
union_specifier: "struct",
|
|
271
|
+
enum_specifier: "enum",
|
|
272
|
+
namespace_definition: "namespace",
|
|
273
|
+
type_definition: "type"
|
|
274
|
+
},
|
|
275
|
+
nameField: {
|
|
276
|
+
function_definition: "declarator",
|
|
277
|
+
template_declaration: "name",
|
|
278
|
+
class_specifier: "name",
|
|
279
|
+
struct_specifier: "name",
|
|
280
|
+
enum_specifier: "name",
|
|
281
|
+
namespace_definition: "name",
|
|
282
|
+
type_definition: "declarator"
|
|
283
|
+
},
|
|
284
|
+
scopeNodes: /* @__PURE__ */ new Set([
|
|
285
|
+
"translation_unit",
|
|
286
|
+
"function_definition",
|
|
287
|
+
"class_specifier",
|
|
288
|
+
"struct_specifier",
|
|
289
|
+
"union_specifier",
|
|
290
|
+
"enum_specifier",
|
|
291
|
+
"namespace_definition"
|
|
292
|
+
]),
|
|
293
|
+
refRules: {
|
|
294
|
+
call_expression: { callType: "call", nameExtractor: cCallExtractor },
|
|
295
|
+
preproc_include: { callType: "import", nameExtractor: cIncludeExtractor },
|
|
296
|
+
// `class Foo : public Bar, private Baz` — the base-class clause.
|
|
297
|
+
base_class_clause: { callType: "inherit", nameExtractor: heritageExtractor }
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
java: {
|
|
301
|
+
declKinds: {
|
|
302
|
+
class_declaration: "class",
|
|
303
|
+
interface_declaration: "interface",
|
|
304
|
+
enum_declaration: "enum",
|
|
305
|
+
record_declaration: "class",
|
|
306
|
+
annotation_type_declaration: "interface",
|
|
307
|
+
method_declaration: "method",
|
|
308
|
+
constructor_declaration: "method",
|
|
309
|
+
field_declaration: "property"
|
|
310
|
+
},
|
|
311
|
+
nameField: {
|
|
312
|
+
class_declaration: "name",
|
|
313
|
+
interface_declaration: "name",
|
|
314
|
+
enum_declaration: "name",
|
|
315
|
+
record_declaration: "name",
|
|
316
|
+
annotation_type_declaration: "name",
|
|
317
|
+
method_declaration: "name",
|
|
318
|
+
constructor_declaration: "name"
|
|
319
|
+
},
|
|
320
|
+
// `field_declaration` has no single `name` field — it carries a list of
|
|
321
|
+
// variable declarators. We emit one Symbol per node using the first
|
|
322
|
+
// identifier-shaped named child (see `extractName` fallback in
|
|
323
|
+
// `visitor.ts`). `int a, b, c;` therefore indexes only `a` — splitting
|
|
324
|
+
// multi-declarator fields into separate Symbols is a separate refactor
|
|
325
|
+
// that needs the visitor to know it has multiple names per node, and no
|
|
326
|
+
// current test relies on it.
|
|
327
|
+
scopeNodes: /* @__PURE__ */ new Set([
|
|
328
|
+
"program",
|
|
329
|
+
"class_declaration",
|
|
330
|
+
"interface_declaration",
|
|
331
|
+
"enum_declaration",
|
|
332
|
+
"record_declaration"
|
|
333
|
+
]),
|
|
334
|
+
refRules: {
|
|
335
|
+
method_invocation: { callType: "call", field: "name" },
|
|
336
|
+
object_creation_expression: { callType: "call", field: "type" },
|
|
337
|
+
// Verified AST: `superclass: (superclass (type_identifier))` and
|
|
338
|
+
// `interfaces: (super_interfaces (type_list ...))` — no underscores.
|
|
339
|
+
superclass: { callType: "inherit", nameExtractor: heritageExtractor },
|
|
340
|
+
super_interfaces: {
|
|
341
|
+
callType: "implement",
|
|
342
|
+
nameExtractor: heritageExtractor
|
|
343
|
+
},
|
|
344
|
+
import_declaration: {
|
|
345
|
+
callType: "import",
|
|
346
|
+
nameExtractor: importFromText(["import "])
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
csharp: {
|
|
351
|
+
// C# 10+ `namespace Foo.Bar;` produces this node type. The legacy block
|
|
352
|
+
// form `namespace Foo.Bar { ... }` produces `namespace_declaration`. Both
|
|
353
|
+
// carry a `qualified_name` child whose text already includes the dots.
|
|
354
|
+
// `using_directive` is intentionally not a declaration. Imports are
|
|
355
|
+
// extracted separately; indexing a using directive as a namespace makes
|
|
356
|
+
// the resolver bind it to its own source file before the real declaration.
|
|
357
|
+
declKinds: {
|
|
358
|
+
file_scoped_namespace_declaration: "namespace",
|
|
359
|
+
class_declaration: "class",
|
|
360
|
+
interface_declaration: "interface",
|
|
361
|
+
struct_declaration: "struct",
|
|
362
|
+
enum_declaration: "enum",
|
|
363
|
+
record_declaration: "class",
|
|
364
|
+
method_declaration: "method",
|
|
365
|
+
constructor_declaration: "method",
|
|
366
|
+
property_declaration: "property",
|
|
367
|
+
field_declaration: "property",
|
|
368
|
+
namespace_declaration: "namespace"
|
|
369
|
+
},
|
|
370
|
+
// Custom name extractor: take the full dotted name verbatim.
|
|
371
|
+
nameExtractor: (node) => {
|
|
372
|
+
const inner = node.namedChild(0);
|
|
373
|
+
if (inner && (inner.type === "qualified_name" || inner.type === "name")) {
|
|
374
|
+
return inner.text;
|
|
375
|
+
}
|
|
376
|
+
return null;
|
|
377
|
+
},
|
|
378
|
+
scopeNodes: /* @__PURE__ */ new Set([
|
|
379
|
+
"compilation_unit",
|
|
380
|
+
"namespace_declaration",
|
|
381
|
+
"class_declaration",
|
|
382
|
+
"interface_declaration",
|
|
383
|
+
"struct_declaration",
|
|
384
|
+
"enum_declaration",
|
|
385
|
+
"record_declaration"
|
|
386
|
+
]),
|
|
387
|
+
refRules: {
|
|
388
|
+
// Verified AST: `invocation_expression function: (identifier)` — the
|
|
389
|
+
// callee field is `function` (C-style), not `name`.
|
|
390
|
+
invocation_expression: { callType: "call", field: "function" },
|
|
391
|
+
object_creation_expression: { callType: "call", field: "type" },
|
|
392
|
+
base_list: { callType: "inherit", nameExtractor: heritageExtractor },
|
|
393
|
+
using_directive: {
|
|
394
|
+
callType: "import",
|
|
395
|
+
nameExtractor: importFromText(["using "])
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
php: {
|
|
400
|
+
declKinds: {
|
|
401
|
+
function_definition: "function",
|
|
402
|
+
method_declaration: "method",
|
|
403
|
+
class_declaration: "class",
|
|
404
|
+
interface_declaration: "interface",
|
|
405
|
+
trait_declaration: "class",
|
|
406
|
+
enum_declaration: "enum",
|
|
407
|
+
namespace_definition: "namespace"
|
|
408
|
+
},
|
|
409
|
+
nameField: {
|
|
410
|
+
function_definition: "name",
|
|
411
|
+
method_declaration: "name",
|
|
412
|
+
class_declaration: "name",
|
|
413
|
+
interface_declaration: "name",
|
|
414
|
+
trait_declaration: "name",
|
|
415
|
+
enum_declaration: "name",
|
|
416
|
+
namespace_definition: "name"
|
|
417
|
+
},
|
|
418
|
+
scopeNodes: /* @__PURE__ */ new Set([
|
|
419
|
+
"program",
|
|
420
|
+
"namespace_definition",
|
|
421
|
+
"class_declaration",
|
|
422
|
+
"interface_declaration",
|
|
423
|
+
"trait_declaration",
|
|
424
|
+
"enum_declaration"
|
|
425
|
+
]),
|
|
426
|
+
refRules: {
|
|
427
|
+
function_call_expression: { callType: "call", field: "function" },
|
|
428
|
+
// Verified AST: `new App\Model\User()` carries a BARE qualified_name
|
|
429
|
+
// child (no `name:` field), so the field default never fires.
|
|
430
|
+
object_creation_expression: { callType: "call", nameExtractor: phpConstructorExtractor },
|
|
431
|
+
base_clause: { callType: "inherit", nameExtractor: heritageExtractor },
|
|
432
|
+
class_interface_clause: {
|
|
433
|
+
callType: "implement",
|
|
434
|
+
nameExtractor: heritageExtractor
|
|
435
|
+
},
|
|
436
|
+
// Verified AST: `namespace_use_declaration (namespace_use_clause
|
|
437
|
+
// (qualified_name ...))` — not `use_declaration`.
|
|
438
|
+
namespace_use_declaration: {
|
|
439
|
+
callType: "import",
|
|
440
|
+
nameExtractor: importFromText(["use "])
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
},
|
|
444
|
+
// ─── Scripting / mobile ────────────────────────────────────────────────────
|
|
445
|
+
ruby: {
|
|
446
|
+
declKinds: {
|
|
447
|
+
method: "function",
|
|
448
|
+
singleton_method: "method",
|
|
449
|
+
class: "class",
|
|
450
|
+
module: "namespace",
|
|
451
|
+
constant: "const"
|
|
452
|
+
},
|
|
453
|
+
nameField: {
|
|
454
|
+
method: "name",
|
|
455
|
+
singleton_method: "name",
|
|
456
|
+
class: "name",
|
|
457
|
+
module: "name",
|
|
458
|
+
constant: "name"
|
|
459
|
+
},
|
|
460
|
+
scopeNodes: /* @__PURE__ */ new Set(["program", "class", "module", "singleton_method", "method"]),
|
|
461
|
+
refRules: {
|
|
462
|
+
// `call` covers both `foo(...)` and `obj.foo(...)` — the extractor
|
|
463
|
+
// records the method leaf, plus `require`/`require_relative` imports.
|
|
464
|
+
call: { callType: "call", nameExtractor: rubyCallExtractor },
|
|
465
|
+
superclass: { callType: "inherit", nameExtractor: heritageExtractor }
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
swift: {
|
|
469
|
+
declKinds: {
|
|
470
|
+
function_declaration: "function",
|
|
471
|
+
class_declaration: "class",
|
|
472
|
+
struct_declaration: "struct",
|
|
473
|
+
enum_declaration: "enum",
|
|
474
|
+
protocol_declaration: "interface",
|
|
475
|
+
actor_declaration: "class",
|
|
476
|
+
extension_declaration: "class",
|
|
477
|
+
initializer: "method",
|
|
478
|
+
property_declaration: "property"
|
|
479
|
+
},
|
|
480
|
+
nameField: {
|
|
481
|
+
function_declaration: "name",
|
|
482
|
+
class_declaration: "name",
|
|
483
|
+
struct_declaration: "name",
|
|
484
|
+
enum_declaration: "name",
|
|
485
|
+
protocol_declaration: "name",
|
|
486
|
+
actor_declaration: "name",
|
|
487
|
+
extension_declaration: "name",
|
|
488
|
+
initializer: "name",
|
|
489
|
+
property_declaration: "name"
|
|
490
|
+
},
|
|
491
|
+
scopeNodes: /* @__PURE__ */ new Set([
|
|
492
|
+
"source_file",
|
|
493
|
+
"class_declaration",
|
|
494
|
+
"struct_declaration",
|
|
495
|
+
"enum_declaration",
|
|
496
|
+
"protocol_declaration",
|
|
497
|
+
"actor_declaration",
|
|
498
|
+
"extension_declaration"
|
|
499
|
+
]),
|
|
500
|
+
refRules: {
|
|
501
|
+
// Verified AST: `call_expression (simple_identifier) (call_suffix …)` —
|
|
502
|
+
// the callee is a bare first child, no field name.
|
|
503
|
+
call_expression: { callType: "call", nameExtractor: firstIdentifierCallExtractor },
|
|
504
|
+
// Verified AST: `inheritance_specifier inherits_from: (user_type …)`.
|
|
505
|
+
inheritance_specifier: { callType: "inherit", nameExtractor: heritageExtractor },
|
|
506
|
+
import_declaration: {
|
|
507
|
+
callType: "import",
|
|
508
|
+
nameExtractor: importFromText(["import ", "import type ", "@testable import "])
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
kotlin: {
|
|
513
|
+
declKinds: {
|
|
514
|
+
class_declaration: "class",
|
|
515
|
+
object_declaration: "class",
|
|
516
|
+
interface_declaration: "interface",
|
|
517
|
+
function_declaration: "function",
|
|
518
|
+
property_declaration: "property",
|
|
519
|
+
type_alias: "type"
|
|
520
|
+
},
|
|
521
|
+
nameField: {
|
|
522
|
+
class_declaration: "name",
|
|
523
|
+
object_declaration: "name",
|
|
524
|
+
interface_declaration: "name",
|
|
525
|
+
function_declaration: "name",
|
|
526
|
+
property_declaration: "name",
|
|
527
|
+
type_alias: "name"
|
|
528
|
+
},
|
|
529
|
+
scopeNodes: /* @__PURE__ */ new Set([
|
|
530
|
+
"source_file",
|
|
531
|
+
"class_declaration",
|
|
532
|
+
"object_declaration",
|
|
533
|
+
"interface_declaration",
|
|
534
|
+
"function_declaration"
|
|
535
|
+
]),
|
|
536
|
+
refRules: {
|
|
537
|
+
call_expression: { callType: "call", nameExtractor: firstIdentifierCallExtractor },
|
|
538
|
+
// Verified AST: `delegation_specifier (user_type (type_identifier))` —
|
|
539
|
+
// the `: Handler` / `: Base()` clause.
|
|
540
|
+
delegation_specifier: { callType: "inherit", nameExtractor: heritageExtractor },
|
|
541
|
+
import_header: {
|
|
542
|
+
callType: "import",
|
|
543
|
+
nameExtractor: importFromText(["import "])
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
},
|
|
547
|
+
elixir: {
|
|
548
|
+
declKinds: {
|
|
549
|
+
// `def foo`, `defp foo`, `defmacro foo`, `macrop foo` all surface as
|
|
550
|
+
// `call` nodes in the tree-sitter grammar — there is no
|
|
551
|
+
// `function_definition`. The `nameExtractor` walks the call's
|
|
552
|
+
// children to pick the right sibling identifier.
|
|
553
|
+
call: "function",
|
|
554
|
+
module: "namespace"
|
|
555
|
+
},
|
|
556
|
+
nameExtractor: (node) => {
|
|
557
|
+
if (node.type === "module") {
|
|
558
|
+
const aliasNode = node.childForFieldName("alias");
|
|
559
|
+
return readFirstString(aliasNode) ?? null;
|
|
560
|
+
}
|
|
561
|
+
if (node.type !== "call") return null;
|
|
562
|
+
const first = node.namedChild(0);
|
|
563
|
+
if (!first) return null;
|
|
564
|
+
const target = first.text;
|
|
565
|
+
if (target !== "def" && target !== "defp" && target !== "defmacro" && target !== "defp_macro" && target !== "macrop" && target !== "defprotocol" && target !== "defguard" && target !== "defguardp") {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
const nameNode = node.namedChild(1);
|
|
569
|
+
return nameNode?.text ?? null;
|
|
570
|
+
},
|
|
571
|
+
scopeNodes: /* @__PURE__ */ new Set(["source", "module"])
|
|
572
|
+
},
|
|
573
|
+
shell: {
|
|
574
|
+
declKinds: {
|
|
575
|
+
function_definition: "function"
|
|
576
|
+
},
|
|
577
|
+
nameField: { function_definition: "name" },
|
|
578
|
+
scopeNodes: /* @__PURE__ */ new Set(["program", "function_definition"])
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
function getQueries(lang) {
|
|
582
|
+
return LANG_QUERIES[lang] ?? DEFAULT_QUERIES;
|
|
583
|
+
}
|
|
584
|
+
function readFirstString(node) {
|
|
585
|
+
if (!node) return null;
|
|
586
|
+
if (node.type === "string_literal" || node.type === "alias") {
|
|
587
|
+
return node.text.replace(/^"|"$/g, "");
|
|
588
|
+
}
|
|
589
|
+
const child = node.namedChild(0);
|
|
590
|
+
return child ? readFirstString(child) : null;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// src/codebase-index/tree-sitter/util.ts
|
|
594
|
+
function lineColAt(offsets, index) {
|
|
595
|
+
let low = 0;
|
|
596
|
+
let high = offsets.length;
|
|
597
|
+
while (low < high) {
|
|
598
|
+
const mid = low + high >>> 1;
|
|
599
|
+
if ((offsets[mid] ?? 0) < index) low = mid + 1;
|
|
600
|
+
else high = mid;
|
|
601
|
+
}
|
|
602
|
+
const lastNl = low > 0 ? offsets[low - 1] ?? -1 : -1;
|
|
603
|
+
return { line: low + 1, col: index - lastNl };
|
|
604
|
+
}
|
|
605
|
+
function newlineOffsets(content) {
|
|
606
|
+
const offsets = [];
|
|
607
|
+
for (let i = 0; i < content.length; i++) {
|
|
608
|
+
if (content.charCodeAt(i) === 10) offsets.push(i);
|
|
609
|
+
}
|
|
610
|
+
return offsets;
|
|
611
|
+
}
|
|
612
|
+
var TREE_SITTER_MAX_FILE_CHARS = 512 * 1024;
|
|
613
|
+
var TREE_SITTER_MAX_SYMBOLS = 500;
|
|
614
|
+
|
|
615
|
+
// src/codebase-index/tree-sitter/visitor.ts
|
|
616
|
+
function visitTree(tree, content, file, lang, queries) {
|
|
617
|
+
const boundedContent = content.length > TREE_SITTER_MAX_FILE_CHARS ? content.slice(0, TREE_SITTER_MAX_FILE_CHARS) : content;
|
|
618
|
+
const nlOffsets = newlineOffsets(boundedContent);
|
|
619
|
+
const symbols = [];
|
|
620
|
+
const refs = [];
|
|
621
|
+
const seenRefs = /* @__PURE__ */ new Set();
|
|
622
|
+
const scopeStack = [];
|
|
623
|
+
function emitRefsForNode(node, rule) {
|
|
624
|
+
const emissions = rule.nameExtractor?.(node) ?? defaultRefTarget(node, rule);
|
|
625
|
+
if (!emissions) return;
|
|
626
|
+
const { line } = lineColAt(nlOffsets, node.startIndex);
|
|
627
|
+
for (const emission of emissions) {
|
|
628
|
+
if (!emission.toName) continue;
|
|
629
|
+
const callType = emission.callType ?? rule.callType;
|
|
630
|
+
const key = `${emission.toName}:${callType}:${line}:${emission.module ?? ""}:${node.startIndex}`;
|
|
631
|
+
if (seenRefs.has(key)) continue;
|
|
632
|
+
seenRefs.add(key);
|
|
633
|
+
refs.push({
|
|
634
|
+
fromId: 0,
|
|
635
|
+
// assignRefsToSymbols attaches owners after insertion
|
|
636
|
+
toName: emission.toName.slice(0, 200),
|
|
637
|
+
callType,
|
|
638
|
+
line,
|
|
639
|
+
lang,
|
|
640
|
+
module: emission.module
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
function defaultRefTarget(node, rule) {
|
|
645
|
+
if (!rule.field) return null;
|
|
646
|
+
const field = node.childForFieldName(rule.field);
|
|
647
|
+
if (!field) return null;
|
|
648
|
+
const leaf = field.text.split(/[.:\\]/).filter(Boolean).pop()?.split(/[<(]/)[0];
|
|
649
|
+
if (!leaf) return null;
|
|
650
|
+
return [{ toName: leaf.trim() }];
|
|
651
|
+
}
|
|
652
|
+
function visit(node, depth) {
|
|
653
|
+
if (symbols.length >= TREE_SITTER_MAX_SYMBOLS) return;
|
|
654
|
+
if (node.isMissing || node.isError) {
|
|
655
|
+
} else {
|
|
656
|
+
const kind = queries.declKinds[node.type];
|
|
657
|
+
if (kind) {
|
|
658
|
+
const emitted = emitSymbol(
|
|
659
|
+
node,
|
|
660
|
+
kind,
|
|
661
|
+
file,
|
|
662
|
+
lang,
|
|
663
|
+
scopeStack,
|
|
664
|
+
boundedContent,
|
|
665
|
+
nlOffsets,
|
|
666
|
+
queries
|
|
667
|
+
);
|
|
668
|
+
if (emitted) symbols.push(emitted);
|
|
669
|
+
}
|
|
670
|
+
const refRule = queries.refRules?.[node.type];
|
|
671
|
+
if (refRule) emitRefsForNode(node, refRule);
|
|
672
|
+
}
|
|
673
|
+
const pushesScope = queries.scopeNodes?.has(node.type) ?? false;
|
|
674
|
+
const pushIdx = pushesScope ? pushScope(scopeStack, node, queries) : -1;
|
|
675
|
+
if (queries.skipNamedChildren) {
|
|
676
|
+
if (pushIdx !== -1) scopeStack.pop();
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
for (const child of node.namedChildren) {
|
|
680
|
+
visit(child, depth + 1);
|
|
681
|
+
if (symbols.length >= TREE_SITTER_MAX_SYMBOLS) {
|
|
682
|
+
if (pushIdx !== -1) scopeStack.pop();
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (pushIdx !== -1) scopeStack.pop();
|
|
687
|
+
}
|
|
688
|
+
visit(tree.rootNode, 0);
|
|
689
|
+
return { symbols, refs };
|
|
690
|
+
}
|
|
691
|
+
function pushScope(scopeStack, node, queries) {
|
|
692
|
+
const name = extractName(node, queries);
|
|
693
|
+
if (!name) return -1;
|
|
694
|
+
scopeStack.push(name);
|
|
695
|
+
return scopeStack.length - 1;
|
|
696
|
+
}
|
|
697
|
+
var IDENTIFIER_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
698
|
+
"identifier",
|
|
699
|
+
"simple_identifier",
|
|
700
|
+
"type_identifier",
|
|
701
|
+
"field_identifier",
|
|
702
|
+
"property_identifier",
|
|
703
|
+
"name",
|
|
704
|
+
"word",
|
|
705
|
+
"variable_name",
|
|
706
|
+
"constant",
|
|
707
|
+
"sym"
|
|
708
|
+
]);
|
|
709
|
+
function extractName(node, queries) {
|
|
710
|
+
if (queries.nameExtractor) {
|
|
711
|
+
const extracted = queries.nameExtractor(node);
|
|
712
|
+
if (extracted) return extracted;
|
|
713
|
+
}
|
|
714
|
+
const fieldName = queries.nameField?.[node.type] ?? "name";
|
|
715
|
+
const field = node.childForFieldName(fieldName);
|
|
716
|
+
if (field) {
|
|
717
|
+
if (IDENTIFIER_NODE_TYPES.has(field.type)) {
|
|
718
|
+
return field.text;
|
|
719
|
+
}
|
|
720
|
+
const inner = field.childForFieldName("name") ?? field.namedChild(0);
|
|
721
|
+
if (inner && IDENTIFIER_NODE_TYPES.has(inner.type)) {
|
|
722
|
+
return inner.text;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
726
|
+
const child = node.namedChild(i);
|
|
727
|
+
if (child && IDENTIFIER_NODE_TYPES.has(child.type)) {
|
|
728
|
+
return child.text;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return null;
|
|
732
|
+
}
|
|
733
|
+
function emitSymbol(node, kind, file, lang, scopeStack, content, nlOffsets, queries) {
|
|
734
|
+
const name = extractName(node, queries);
|
|
735
|
+
if (!name) return null;
|
|
736
|
+
const pos = node.startIndex;
|
|
737
|
+
const { line, col } = lineColAt(nlOffsets, pos);
|
|
738
|
+
const end = Math.min(node.endIndex, content.length);
|
|
739
|
+
const signature = content.slice(pos, end).replace(/\s+/g, " ").trim().slice(0, 500);
|
|
740
|
+
const scope = scopeStack.join(".");
|
|
741
|
+
const text = [name, signature].filter(Boolean).join(" | ").trim().slice(0, 1e3);
|
|
742
|
+
return {
|
|
743
|
+
id: 0,
|
|
744
|
+
// caller assigns during bulk insertion
|
|
745
|
+
lang,
|
|
746
|
+
kind,
|
|
747
|
+
name: name.slice(0, 200),
|
|
748
|
+
file,
|
|
749
|
+
line,
|
|
750
|
+
col,
|
|
751
|
+
signature,
|
|
752
|
+
docComment: "",
|
|
753
|
+
// doc-comment extraction lands with ref emission on Day 4
|
|
754
|
+
scope,
|
|
755
|
+
text
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// src/codebase-index/tree-sitter-parser.ts
|
|
760
|
+
var WASM_DIR = fileURLToPath(new URL("./wasm/", import.meta.url));
|
|
761
|
+
var RUNTIME_WASM = path.join(WASM_DIR, "tree-sitter-runtime.wasm");
|
|
762
|
+
var LANG_TO_GRAMMAR = {
|
|
763
|
+
c: "c",
|
|
764
|
+
cpp: "cpp",
|
|
765
|
+
java: "java",
|
|
766
|
+
csharp: "c_sharp",
|
|
767
|
+
// tree-sitter directory uses underscore
|
|
768
|
+
php: "php",
|
|
769
|
+
ruby: "ruby",
|
|
770
|
+
swift: "swift",
|
|
771
|
+
kotlin: "kotlin",
|
|
772
|
+
shell: "bash",
|
|
773
|
+
// we treat `.sh` / `.bash` / `.zsh` via the bash grammar
|
|
774
|
+
// Go/Python/Rust are opt-in only (see goOptIn / pyOptIn / rsOptIn below)
|
|
775
|
+
elixir: "elixir"
|
|
776
|
+
};
|
|
777
|
+
var GO_OPT_IN = "WRONGSTACK_USE_TS_GO";
|
|
778
|
+
var PY_OPT_IN = "WRONGSTACK_USE_TS_PY";
|
|
779
|
+
var RS_OPT_IN = "WRONGSTACK_USE_TS_RS";
|
|
780
|
+
function optInEnabled(env) {
|
|
781
|
+
return process.env[env] === "1" || process.env[env] === "true";
|
|
782
|
+
}
|
|
783
|
+
var runtimePromise = null;
|
|
784
|
+
var languageCache = /* @__PURE__ */ new Map();
|
|
785
|
+
function getRuntime() {
|
|
786
|
+
if (!runtimePromise) {
|
|
787
|
+
runtimePromise = (async () => {
|
|
788
|
+
const mod = await import("web-tree-sitter");
|
|
789
|
+
const init = () => mod.Parser.init({ locateFile: () => RUNTIME_WASM });
|
|
790
|
+
return { Parser: mod.Parser, Language: mod.Language, init };
|
|
791
|
+
})();
|
|
792
|
+
}
|
|
793
|
+
return runtimePromise;
|
|
794
|
+
}
|
|
795
|
+
async function loadLanguage(lang) {
|
|
796
|
+
const existing = languageCache.get(lang);
|
|
797
|
+
if (existing) return existing;
|
|
798
|
+
const promise = (async () => {
|
|
799
|
+
const grammarName = resolveGrammarName(lang);
|
|
800
|
+
if (!grammarName) {
|
|
801
|
+
throw new Error(`tree-sitter: no grammar registered for lang "${lang}"`);
|
|
802
|
+
}
|
|
803
|
+
const wasmPath = path.join(WASM_DIR, grammarName, `tree-sitter-${grammarName}.wasm`);
|
|
804
|
+
const { Language, init } = await getRuntime();
|
|
805
|
+
await init();
|
|
806
|
+
const languageObj = await Language.load(wasmPath);
|
|
807
|
+
return { lang, Language: languageObj };
|
|
808
|
+
})();
|
|
809
|
+
languageCache.set(lang, promise);
|
|
810
|
+
return promise;
|
|
811
|
+
}
|
|
812
|
+
function resolveGrammarName(lang) {
|
|
813
|
+
if (lang === "go" && optInEnabled(GO_OPT_IN)) return "go";
|
|
814
|
+
if (lang === "py" && optInEnabled(PY_OPT_IN)) return "python";
|
|
815
|
+
if (lang === "rs" && optInEnabled(RS_OPT_IN)) return "rust";
|
|
816
|
+
return LANG_TO_GRAMMAR[lang];
|
|
817
|
+
}
|
|
818
|
+
function isTreeSitterSupported(lang) {
|
|
819
|
+
return resolveGrammarName(lang) !== void 0;
|
|
820
|
+
}
|
|
821
|
+
function getGrammarWasmPath(lang) {
|
|
822
|
+
const name = resolveGrammarName(lang);
|
|
823
|
+
if (!name) return void 0;
|
|
824
|
+
return path.join(WASM_DIR, name, `tree-sitter-${name}.wasm`);
|
|
825
|
+
}
|
|
826
|
+
async function parseSymbols(opts) {
|
|
827
|
+
const { file, content, lang } = opts;
|
|
828
|
+
if (!isTreeSitterSupported(lang)) {
|
|
829
|
+
return { file, lang, symbols: [], mtimeMs: Date.now() };
|
|
830
|
+
}
|
|
831
|
+
try {
|
|
832
|
+
const { Parser } = await getRuntime();
|
|
833
|
+
const cached = await loadLanguage(lang);
|
|
834
|
+
const parser = new Parser();
|
|
835
|
+
parser.setLanguage(cached.Language);
|
|
836
|
+
const tree = parser.parse(content);
|
|
837
|
+
if (!tree) {
|
|
838
|
+
return { file, lang, symbols: [], mtimeMs: Date.now() };
|
|
839
|
+
}
|
|
840
|
+
const { symbols, refs } = visitTree(tree, content, file, lang, getQueries(lang));
|
|
841
|
+
parser.delete();
|
|
842
|
+
tree.delete();
|
|
843
|
+
return { file, lang, symbols, refs, mtimeMs: Date.now() };
|
|
844
|
+
} catch {
|
|
845
|
+
return { file, lang, symbols: [], mtimeMs: Date.now() };
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
async function loadTreeSitterLanguage(lang) {
|
|
849
|
+
const cached = await loadLanguage(lang);
|
|
850
|
+
return cached.Language;
|
|
851
|
+
}
|
|
852
|
+
async function __smokeRootType(opts) {
|
|
853
|
+
if (!isTreeSitterSupported(opts.lang)) {
|
|
854
|
+
throw new Error(`tree-sitter: no grammar registered for lang "${opts.lang}"`);
|
|
855
|
+
}
|
|
856
|
+
const { Parser } = await getRuntime();
|
|
857
|
+
const cached = await loadLanguage(opts.lang);
|
|
858
|
+
const parser = new Parser();
|
|
859
|
+
parser.setLanguage(cached.Language);
|
|
860
|
+
let tree = null;
|
|
861
|
+
try {
|
|
862
|
+
tree = parser.parse(opts.content);
|
|
863
|
+
if (!tree) throw new Error("tree-sitter: parser.parse returned null");
|
|
864
|
+
return tree.rootNode.type;
|
|
865
|
+
} finally {
|
|
866
|
+
tree?.delete();
|
|
867
|
+
parser.delete();
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
async function parseTreeSitterAst(opts) {
|
|
871
|
+
const grammar = resolveGrammarName(opts.lang) ?? (opts.lang === "go" ? "go" : opts.lang === "py" ? "python" : opts.lang === "rs" ? "rust" : void 0);
|
|
872
|
+
if (!grammar) return null;
|
|
873
|
+
try {
|
|
874
|
+
const { Parser, Language, init } = await getRuntime();
|
|
875
|
+
await init();
|
|
876
|
+
const wasmPath = path.join(WASM_DIR, grammar, `tree-sitter-${grammar}.wasm`);
|
|
877
|
+
const languageObj = await Language.load(wasmPath);
|
|
878
|
+
const parser = new Parser();
|
|
879
|
+
parser.setLanguage(languageObj);
|
|
880
|
+
const tree = parser.parse(opts.content);
|
|
881
|
+
if (!tree) {
|
|
882
|
+
parser.delete();
|
|
883
|
+
return null;
|
|
884
|
+
}
|
|
885
|
+
return { tree, parser };
|
|
886
|
+
} catch {
|
|
887
|
+
return null;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
export {
|
|
892
|
+
getGrammarWasmPath,
|
|
893
|
+
parseSymbols,
|
|
894
|
+
loadTreeSitterLanguage,
|
|
895
|
+
__smokeRootType,
|
|
896
|
+
parseTreeSitterAst
|
|
897
|
+
};
|
|
898
|
+
//# sourceMappingURL=chunk-EEOFQDT6.js.map
|