@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
package/dist/chunk-ZKC5UNGD.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
// src/codebase-index/parser-output.ts
|
|
2
|
-
var CALL_TYPES = /* @__PURE__ */ new Set([
|
|
3
|
-
"call",
|
|
4
|
-
"type_ref",
|
|
5
|
-
"inherit",
|
|
6
|
-
"implement",
|
|
7
|
-
"import"
|
|
8
|
-
]);
|
|
9
|
-
function coerceSymbols(value) {
|
|
10
|
-
if (!Array.isArray(value)) return [];
|
|
11
|
-
return value.flatMap((entry) => {
|
|
12
|
-
const candidate = entry;
|
|
13
|
-
if (typeof candidate.name !== "string" || typeof candidate.kind !== "string") return [];
|
|
14
|
-
return [
|
|
15
|
-
{
|
|
16
|
-
name: candidate.name,
|
|
17
|
-
kind: candidate.kind,
|
|
18
|
-
line: typeof candidate.line === "number" ? candidate.line : 1,
|
|
19
|
-
col: typeof candidate.col === "number" ? candidate.col : 0,
|
|
20
|
-
signature: typeof candidate.signature === "string" ? candidate.signature : "",
|
|
21
|
-
scope: typeof candidate.scope === "string" ? candidate.scope : ""
|
|
22
|
-
}
|
|
23
|
-
];
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
function coerceRefs(value, lang) {
|
|
27
|
-
if (!Array.isArray(value)) return [];
|
|
28
|
-
return value.flatMap((entry) => {
|
|
29
|
-
const candidate = entry;
|
|
30
|
-
if (typeof candidate.toName !== "string" || !candidate.toName) return [];
|
|
31
|
-
if (typeof candidate.callType !== "string" || !CALL_TYPES.has(candidate.callType)) return [];
|
|
32
|
-
const module = typeof candidate.module === "string" && candidate.module ? candidate.module : void 0;
|
|
33
|
-
return [
|
|
34
|
-
{
|
|
35
|
-
fromId: 0,
|
|
36
|
-
toName: candidate.toName,
|
|
37
|
-
callType: candidate.callType,
|
|
38
|
-
line: typeof candidate.line === "number" ? candidate.line : 1,
|
|
39
|
-
lang,
|
|
40
|
-
module
|
|
41
|
-
}
|
|
42
|
-
];
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
function parseParserOutput(stdout, lang) {
|
|
46
|
-
const trimmed = stdout.trim();
|
|
47
|
-
if (!trimmed) return { symbols: [], refs: [] };
|
|
48
|
-
let parsed;
|
|
49
|
-
try {
|
|
50
|
-
parsed = JSON.parse(trimmed);
|
|
51
|
-
} catch {
|
|
52
|
-
return { symbols: [], refs: [] };
|
|
53
|
-
}
|
|
54
|
-
if (Array.isArray(parsed)) return { symbols: coerceSymbols(parsed), refs: [] };
|
|
55
|
-
const record = parsed;
|
|
56
|
-
return {
|
|
57
|
-
symbols: coerceSymbols(record.symbols),
|
|
58
|
-
refs: dedupeRefs(coerceRefs(record.refs, lang))
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function parseParserBatchOutput(stdout, lang) {
|
|
62
|
-
const trimmed = stdout.trim();
|
|
63
|
-
if (!trimmed) return [];
|
|
64
|
-
let parsed;
|
|
65
|
-
try {
|
|
66
|
-
parsed = JSON.parse(trimmed);
|
|
67
|
-
} catch {
|
|
68
|
-
return [];
|
|
69
|
-
}
|
|
70
|
-
if (!parsed || typeof parsed !== "object") return [];
|
|
71
|
-
const results = parsed.results;
|
|
72
|
-
if (!Array.isArray(results)) return [];
|
|
73
|
-
return results.flatMap((entry) => {
|
|
74
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) return [];
|
|
75
|
-
const candidate = entry;
|
|
76
|
-
if (typeof candidate.file !== "string" || !candidate.file) return [];
|
|
77
|
-
return [
|
|
78
|
-
{
|
|
79
|
-
file: candidate.file,
|
|
80
|
-
error: typeof candidate.error === "string" && candidate.error ? candidate.error : void 0,
|
|
81
|
-
symbols: coerceSymbols(candidate.symbols),
|
|
82
|
-
refs: dedupeRefs(coerceRefs(candidate.refs, lang))
|
|
83
|
-
}
|
|
84
|
-
];
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
function dedupeRefs(refs) {
|
|
88
|
-
const seen = /* @__PURE__ */ new Set();
|
|
89
|
-
return refs.filter((ref) => {
|
|
90
|
-
const key = `${ref.toName}:${ref.callType}:${ref.line}:${ref.module ?? ""}`;
|
|
91
|
-
if (seen.has(key)) return false;
|
|
92
|
-
seen.add(key);
|
|
93
|
-
return true;
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// src/codebase-index/perf-metrics.ts
|
|
98
|
-
var counters = {
|
|
99
|
-
filesystemBytesRead: 0,
|
|
100
|
-
filesystemReadCount: 0,
|
|
101
|
-
parserGateWaitMs: 0,
|
|
102
|
-
parserGateCalls: 0,
|
|
103
|
-
parserSubprocessCount: 0,
|
|
104
|
-
ipcPendingPeak: 0,
|
|
105
|
-
writeQueueWaitMs: 0,
|
|
106
|
-
writeQueueCalls: 0
|
|
107
|
-
};
|
|
108
|
-
function resetCodebaseIndexPerfMetrics() {
|
|
109
|
-
for (const key of Object.keys(counters)) {
|
|
110
|
-
counters[key] = 0;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function getCodebaseIndexPerfSnapshot() {
|
|
114
|
-
return { ...counters };
|
|
115
|
-
}
|
|
116
|
-
function recordFilesystemRead(bytes) {
|
|
117
|
-
counters.filesystemBytesRead += Math.max(0, bytes);
|
|
118
|
-
counters.filesystemReadCount++;
|
|
119
|
-
}
|
|
120
|
-
function recordParserGateWait(waitMs) {
|
|
121
|
-
counters.parserGateWaitMs += Math.max(0, waitMs);
|
|
122
|
-
counters.parserGateCalls++;
|
|
123
|
-
}
|
|
124
|
-
function recordParserSubprocess() {
|
|
125
|
-
counters.parserSubprocessCount++;
|
|
126
|
-
}
|
|
127
|
-
function recordIpcPending(depth) {
|
|
128
|
-
counters.ipcPendingPeak = Math.max(counters.ipcPendingPeak, depth);
|
|
129
|
-
}
|
|
130
|
-
function recordWriteQueueWait(waitMs) {
|
|
131
|
-
counters.writeQueueWaitMs += Math.max(0, waitMs);
|
|
132
|
-
counters.writeQueueCalls++;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// src/codebase-index/spawn-gate.ts
|
|
136
|
-
var chain = Promise.resolve();
|
|
137
|
-
function withSpawnGate(fn) {
|
|
138
|
-
const queuedAt = performance.now();
|
|
139
|
-
const run = chain.then(
|
|
140
|
-
() => {
|
|
141
|
-
recordParserGateWait(performance.now() - queuedAt);
|
|
142
|
-
return fn();
|
|
143
|
-
},
|
|
144
|
-
() => {
|
|
145
|
-
recordParserGateWait(performance.now() - queuedAt);
|
|
146
|
-
return fn();
|
|
147
|
-
}
|
|
148
|
-
);
|
|
149
|
-
chain = run.then(
|
|
150
|
-
() => void 0,
|
|
151
|
-
() => void 0
|
|
152
|
-
);
|
|
153
|
-
return run;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export {
|
|
157
|
-
parseParserOutput,
|
|
158
|
-
parseParserBatchOutput,
|
|
159
|
-
resetCodebaseIndexPerfMetrics,
|
|
160
|
-
getCodebaseIndexPerfSnapshot,
|
|
161
|
-
recordFilesystemRead,
|
|
162
|
-
recordParserSubprocess,
|
|
163
|
-
recordIpcPending,
|
|
164
|
-
recordWriteQueueWait,
|
|
165
|
-
withSpawnGate
|
|
166
|
-
};
|
|
167
|
-
//# sourceMappingURL=chunk-ZKC5UNGD.js.map
|
|
@@ -1,474 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseParserOutput,
|
|
3
|
-
recordParserSubprocess,
|
|
4
|
-
withSpawnGate
|
|
5
|
-
} from "./chunk-ZKC5UNGD.js";
|
|
6
|
-
import {
|
|
7
|
-
detectLang
|
|
8
|
-
} from "./chunk-YOHO4DVT.js";
|
|
9
|
-
import {
|
|
10
|
-
resolveWin32Command
|
|
11
|
-
} from "./chunk-XZLVJD56.js";
|
|
12
|
-
|
|
13
|
-
// src/codebase-index/go-parser.ts
|
|
14
|
-
import { spawn } from "node:child_process";
|
|
15
|
-
import * as os from "node:os";
|
|
16
|
-
import * as path from "node:path";
|
|
17
|
-
import * as fs from "node:fs/promises";
|
|
18
|
-
import { StringDecoder } from "node:string_decoder";
|
|
19
|
-
async function parseSymbols(opts) {
|
|
20
|
-
const { file, content, lang } = opts;
|
|
21
|
-
try {
|
|
22
|
-
const parsed = await withSpawnGate(() => syncGoParse(file, content, lang));
|
|
23
|
-
if (parsed.symbols.length > 0) {
|
|
24
|
-
return parsed;
|
|
25
|
-
}
|
|
26
|
-
const fallback = fallbackParse(file, content, lang);
|
|
27
|
-
return parsed.refs?.length ? { ...fallback, refs: parsed.refs } : fallback;
|
|
28
|
-
} catch {
|
|
29
|
-
return fallbackParse(file, content, lang);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function fallbackParse(filePath, content, lang) {
|
|
33
|
-
if (!/^\s*package\s+[A-Za-z_]\w*/m.test(content) || hasUnbalancedDelimiters(content)) {
|
|
34
|
-
return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
|
|
35
|
-
}
|
|
36
|
-
const symbols = [];
|
|
37
|
-
const packageName = content.match(/^\s*package\s+([A-Za-z_]\w*)/m)?.[1] ?? "";
|
|
38
|
-
const lines = content.split(/\r?\n/);
|
|
39
|
-
for (const [idx, line] of lines.entries()) {
|
|
40
|
-
const trimmed = line.trimStart();
|
|
41
|
-
const col = line.length - trimmed.length;
|
|
42
|
-
const fn = /^func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)\s*\(/.exec(trimmed);
|
|
43
|
-
if (fn?.[1]) {
|
|
44
|
-
addFallbackSymbol(symbols, {
|
|
45
|
-
filePath,
|
|
46
|
-
lang,
|
|
47
|
-
kind: trimmed.startsWith("func (") ? "method" : "function",
|
|
48
|
-
name: fn[1],
|
|
49
|
-
line: idx + 1,
|
|
50
|
-
col,
|
|
51
|
-
signature: trimmed,
|
|
52
|
-
scope: packageName ? `${packageName}.${fn[1]}` : fn[1]
|
|
53
|
-
});
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const typeDecl = /^type\s+([A-Za-z_]\w*)\b/.exec(trimmed);
|
|
57
|
-
if (typeDecl?.[1]) {
|
|
58
|
-
addFallbackSymbol(symbols, {
|
|
59
|
-
filePath,
|
|
60
|
-
lang,
|
|
61
|
-
kind: "type",
|
|
62
|
-
name: typeDecl[1],
|
|
63
|
-
line: idx + 1,
|
|
64
|
-
col,
|
|
65
|
-
signature: trimmed,
|
|
66
|
-
scope: packageName
|
|
67
|
-
});
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
const valueDecl = /^(const|var)\s+([A-Za-z_]\w*)\b/.exec(trimmed);
|
|
71
|
-
if (valueDecl?.[1] && valueDecl[2]) {
|
|
72
|
-
addFallbackSymbol(symbols, {
|
|
73
|
-
filePath,
|
|
74
|
-
lang,
|
|
75
|
-
kind: valueDecl[1],
|
|
76
|
-
name: valueDecl[2],
|
|
77
|
-
line: idx + 1,
|
|
78
|
-
col,
|
|
79
|
-
signature: trimmed,
|
|
80
|
-
scope: packageName
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return { file: filePath, lang, symbols, mtimeMs: Date.now() };
|
|
85
|
-
}
|
|
86
|
-
function addFallbackSymbol(symbols, opts) {
|
|
87
|
-
symbols.push({
|
|
88
|
-
id: 0,
|
|
89
|
-
lang: opts.lang,
|
|
90
|
-
kind: opts.kind,
|
|
91
|
-
name: opts.name,
|
|
92
|
-
file: opts.filePath,
|
|
93
|
-
line: opts.line,
|
|
94
|
-
col: opts.col,
|
|
95
|
-
signature: opts.signature,
|
|
96
|
-
docComment: "",
|
|
97
|
-
scope: opts.scope,
|
|
98
|
-
text: `${opts.name} ${opts.signature}`.trim()
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
function hasUnbalancedDelimiters(content) {
|
|
102
|
-
const pairs = { "(": ")", "[": "]", "{": "}" };
|
|
103
|
-
const closers = new Set(Object.values(pairs));
|
|
104
|
-
const stack = [];
|
|
105
|
-
for (const ch of content) {
|
|
106
|
-
if (pairs[ch]) {
|
|
107
|
-
stack.push(pairs[ch]);
|
|
108
|
-
} else if (closers.has(ch) && stack.pop() !== ch) {
|
|
109
|
-
return true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return stack.length > 0;
|
|
113
|
-
}
|
|
114
|
-
var GO_PARSE_SCRIPT = `
|
|
115
|
-
package main
|
|
116
|
-
|
|
117
|
-
import (
|
|
118
|
-
"encoding/json"
|
|
119
|
-
"fmt"
|
|
120
|
-
"go/ast"
|
|
121
|
-
"go/parser"
|
|
122
|
-
"go/token"
|
|
123
|
-
"io"
|
|
124
|
-
"os"
|
|
125
|
-
"strconv"
|
|
126
|
-
"strings"
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
type Sym struct {
|
|
130
|
-
Name string \`json:"name"\`
|
|
131
|
-
Kind string \`json:"kind"\`
|
|
132
|
-
Line int \`json:"line"\`
|
|
133
|
-
Col int \`json:"col"\`
|
|
134
|
-
Signature string \`json:"signature"\`
|
|
135
|
-
Scope string \`json:"scope"\`
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Ref is a cross-reference emitted alongside the symbols, so one \`go run\`
|
|
139
|
-
// yields both. Module is the import path for CallType "import", else empty.
|
|
140
|
-
type Ref struct {
|
|
141
|
-
ToName string \`json:"toName"\`
|
|
142
|
-
CallType string \`json:"callType"\`
|
|
143
|
-
Line int \`json:"line"\`
|
|
144
|
-
Module string \`json:"module"\`
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
type Result struct {
|
|
148
|
-
Symbols []Sym \`json:"symbols"\`
|
|
149
|
-
Refs []Ref \`json:"refs"\`
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
func emptyResult() string {
|
|
153
|
-
return "{\\"symbols\\":[],\\"refs\\":[]}"
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
func main() {
|
|
157
|
-
src, err := io.ReadAll(os.Stdin)
|
|
158
|
-
if err != nil {
|
|
159
|
-
fmt.Print(emptyResult())
|
|
160
|
-
return
|
|
161
|
-
}
|
|
162
|
-
fset := token.NewFileSet()
|
|
163
|
-
node, err := parser.ParseFile(fset, "src.go", src, 0)
|
|
164
|
-
if err != nil {
|
|
165
|
-
fmt.Print(emptyResult())
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
var syms []Sym
|
|
170
|
-
|
|
171
|
-
// Package-level scope
|
|
172
|
-
pkgScope := node.Name.Name
|
|
173
|
-
|
|
174
|
-
// Collect all top-level declarations
|
|
175
|
-
for _, decl := range node.Decls {
|
|
176
|
-
switch d := decl.(type) {
|
|
177
|
-
case *ast.FuncDecl:
|
|
178
|
-
name := d.Name.Name
|
|
179
|
-
kind := "function"
|
|
180
|
-
scope := pkgScope
|
|
181
|
-
if d.Recv != nil && len(d.Recv.List) > 0 {
|
|
182
|
-
scope = pkgScope + "." + recvTypeName(d.Recv.List[0].Type) + "." + name
|
|
183
|
-
kind = "method"
|
|
184
|
-
} else {
|
|
185
|
-
scope = pkgScope + "." + name
|
|
186
|
-
}
|
|
187
|
-
pos := fset.Position(d.Pos())
|
|
188
|
-
sig := formatFuncSig(d)
|
|
189
|
-
syms = append(syms, Sym{Name: name, Kind: kind, Line: pos.Line, Col: pos.Column - 1, Signature: sig, Scope: scope})
|
|
190
|
-
|
|
191
|
-
case *ast.GenDecl:
|
|
192
|
-
for _, spec := range d.Specs {
|
|
193
|
-
switch s := spec.(type) {
|
|
194
|
-
case *ast.TypeSpec:
|
|
195
|
-
name := s.Name.Name
|
|
196
|
-
pos := fset.Position(s.Pos())
|
|
197
|
-
sig := "type " + name
|
|
198
|
-
if s.TypeParams != nil {
|
|
199
|
-
sig += formatTypeParams(s.TypeParams)
|
|
200
|
-
}
|
|
201
|
-
if st, ok := s.Type.(*ast.StructType); ok {
|
|
202
|
-
sig += " = struct { " + formatFields(st.Fields.List) + " }"
|
|
203
|
-
} else if it, ok := s.Type.(*ast.InterfaceType); ok {
|
|
204
|
-
sig += " = interface { " + formatMethods(it.Methods.List) + " }"
|
|
205
|
-
} else {
|
|
206
|
-
sig += " = " + formatType(s.Type)
|
|
207
|
-
}
|
|
208
|
-
syms = append(syms, Sym{Name: name, Kind: "type", Line: pos.Line, Col: pos.Column - 1, Signature: sig, Scope: pkgScope})
|
|
209
|
-
|
|
210
|
-
case *ast.ValueSpec:
|
|
211
|
-
for _, n := range s.Names {
|
|
212
|
-
name := n.Name
|
|
213
|
-
pos := fset.Position(n.Pos())
|
|
214
|
-
kind := "var"
|
|
215
|
-
if d.Tok == token.CONST {
|
|
216
|
-
kind = "const"
|
|
217
|
-
}
|
|
218
|
-
sig := kind + " " + name
|
|
219
|
-
if s.Type != nil {
|
|
220
|
-
sig += " " + formatType(s.Type)
|
|
221
|
-
}
|
|
222
|
-
syms = append(syms, Sym{Name: name, Kind: kind, Line: pos.Line, Col: pos.Column - 1, Signature: sig, Scope: pkgScope})
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
refs := []Ref{}
|
|
230
|
-
ast.Inspect(node, func(n ast.Node) bool {
|
|
231
|
-
switch expr := n.(type) {
|
|
232
|
-
case *ast.CallExpr:
|
|
233
|
-
line := fset.Position(expr.Pos()).Line
|
|
234
|
-
switch fun := expr.Fun.(type) {
|
|
235
|
-
case *ast.Ident:
|
|
236
|
-
refs = append(refs, Ref{ToName: fun.Name, CallType: "call", Line: line})
|
|
237
|
-
case *ast.SelectorExpr:
|
|
238
|
-
// Record the selected name (\`Join\` of \`filepath.Join\`): it is the
|
|
239
|
-
// declared symbol name, so it resolves the same way the TypeScript
|
|
240
|
-
// and Python extractors' call refs do.
|
|
241
|
-
refs = append(refs, Ref{ToName: fun.Sel.Name, CallType: "call", Line: line})
|
|
242
|
-
}
|
|
243
|
-
case *ast.ImportSpec:
|
|
244
|
-
if expr.Path != nil {
|
|
245
|
-
if importPath, uerr := strconv.Unquote(expr.Path.Value); uerr == nil {
|
|
246
|
-
line := fset.Position(expr.Pos()).Line
|
|
247
|
-
// A Go import names a package, not a symbol; the package's
|
|
248
|
-
// last path segment is the name it is referenced by.
|
|
249
|
-
name := importPath
|
|
250
|
-
if idx := strings.LastIndex(importPath, "/"); idx >= 0 {
|
|
251
|
-
name = importPath[idx+1:]
|
|
252
|
-
}
|
|
253
|
-
refs = append(refs, Ref{ToName: name, CallType: "import", Line: line, Module: importPath})
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return true
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
if syms == nil {
|
|
261
|
-
syms = []Sym{}
|
|
262
|
-
}
|
|
263
|
-
data, err := json.Marshal(Result{Symbols: syms, Refs: refs})
|
|
264
|
-
if err != nil {
|
|
265
|
-
fmt.Print(emptyResult())
|
|
266
|
-
return
|
|
267
|
-
}
|
|
268
|
-
fmt.Print(string(data))
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
func recvTypeName(t ast.Expr) string {
|
|
272
|
-
switch v := t.(type) {
|
|
273
|
-
case *ast.Ident:
|
|
274
|
-
return v.Name
|
|
275
|
-
case *ast.StarExpr:
|
|
276
|
-
return recvTypeName(v.X)
|
|
277
|
-
default:
|
|
278
|
-
return "?"
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
func formatFuncSig(d *ast.FuncDecl) string {
|
|
283
|
-
scope := ""
|
|
284
|
-
if d.Recv != nil && len(d.Recv.List) > 0 {
|
|
285
|
-
scope = "(" + formatFieldList(d.Recv.List) + ") "
|
|
286
|
-
}
|
|
287
|
-
scope += formatFuncType(d.Type)
|
|
288
|
-
return "func " + scope
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
func formatFuncType(f *ast.FuncType) string {
|
|
292
|
-
params := formatFieldList(f.Params.List)
|
|
293
|
-
results := ""
|
|
294
|
-
if f.Results != nil {
|
|
295
|
-
results = " -> " + formatFieldList(f.Results.List)
|
|
296
|
-
}
|
|
297
|
-
return params + results
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
func formatFieldList(fields []*ast.Field) string {
|
|
301
|
-
if len(fields) == 0 {
|
|
302
|
-
return "()"
|
|
303
|
-
}
|
|
304
|
-
names := make([]string, 0, len(fields))
|
|
305
|
-
for _, f := range fields {
|
|
306
|
-
name := ""
|
|
307
|
-
if len(f.Names) > 0 {
|
|
308
|
-
name = f.Names[0].Name
|
|
309
|
-
}
|
|
310
|
-
t := formatType(f.Type)
|
|
311
|
-
if name != "" {
|
|
312
|
-
names = append(names, name+" "+t)
|
|
313
|
-
} else {
|
|
314
|
-
names = append(names, t)
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
return "(" + strings.Join(names, ", ") + ")"
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
func formatFields(fields []*ast.Field) string {
|
|
321
|
-
lines := make([]string, 0)
|
|
322
|
-
for _, f := range fields {
|
|
323
|
-
name := ""
|
|
324
|
-
if len(f.Names) > 0 {
|
|
325
|
-
name = f.Names[0].Name
|
|
326
|
-
}
|
|
327
|
-
t := formatType(f.Type)
|
|
328
|
-
if name != "" {
|
|
329
|
-
lines = append(lines, name+" "+t)
|
|
330
|
-
} else {
|
|
331
|
-
lines = append(lines, t)
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
return strings.Join(lines, "; ")
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
func formatMethods(fields []*ast.Field) string {
|
|
338
|
-
return formatFields(fields)
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
func formatTypeParams(tp *ast.FieldList) string {
|
|
342
|
-
if tp == nil || len(tp.List) == 0 {
|
|
343
|
-
return ""
|
|
344
|
-
}
|
|
345
|
-
params := make([]string, len(tp.List))
|
|
346
|
-
for i, p := range tp.List {
|
|
347
|
-
if len(p.Names) > 0 {
|
|
348
|
-
params[i] = p.Names[0].Name
|
|
349
|
-
} else {
|
|
350
|
-
params[i] = "T"
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
return "[" + strings.Join(params, ", ") + "]"
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
func formatType(t ast.Expr) string {
|
|
357
|
-
if t == nil {
|
|
358
|
-
return "?"
|
|
359
|
-
}
|
|
360
|
-
switch v := t.(type) {
|
|
361
|
-
case *ast.Ident:
|
|
362
|
-
return v.Name
|
|
363
|
-
case *ast.SelectorExpr:
|
|
364
|
-
return formatType(v.X) + "." + v.Sel.Name
|
|
365
|
-
case *ast.StarExpr:
|
|
366
|
-
return "*" + formatType(v.X)
|
|
367
|
-
case *ast.ArrayType:
|
|
368
|
-
if v.Len == nil {
|
|
369
|
-
return "[]" + formatType(v.Elt)
|
|
370
|
-
}
|
|
371
|
-
return "[...]" + formatType(v.Elt)
|
|
372
|
-
case *ast.MapType:
|
|
373
|
-
return "map[" + formatType(v.Key) + "]" + formatType(v.Value)
|
|
374
|
-
case *ast.InterfaceType:
|
|
375
|
-
return "interface{}"
|
|
376
|
-
case *ast.StructType:
|
|
377
|
-
return "struct{}"
|
|
378
|
-
case *ast.FuncType:
|
|
379
|
-
return formatFuncType(v)
|
|
380
|
-
case *ast.ChanType:
|
|
381
|
-
return "chan " + formatType(v.Value)
|
|
382
|
-
case *ast.BasicLit:
|
|
383
|
-
return v.Value
|
|
384
|
-
case *ast.IndexExpr:
|
|
385
|
-
// Generic instantiation with one type arg, e.g. Logger[int].
|
|
386
|
-
return formatType(v.X) + "[" + formatType(v.Index) + "]"
|
|
387
|
-
case *ast.IndexListExpr:
|
|
388
|
-
// Generic instantiation with multiple type args, e.g. Map[K, V].
|
|
389
|
-
args := make([]string, len(v.Indices))
|
|
390
|
-
for i, idx := range v.Indices {
|
|
391
|
-
args[i] = formatType(idx)
|
|
392
|
-
}
|
|
393
|
-
return formatType(v.X) + "[" + strings.Join(args, ", ") + "]"
|
|
394
|
-
default:
|
|
395
|
-
return "?"
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
`;
|
|
399
|
-
var _cachedGoScriptPath = null;
|
|
400
|
-
async function syncGoParse(filePath, content, lang) {
|
|
401
|
-
try {
|
|
402
|
-
let scriptPath = _cachedGoScriptPath;
|
|
403
|
-
if (!scriptPath) {
|
|
404
|
-
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "ws-go-parse-"));
|
|
405
|
-
scriptPath = path.join(tmpDir, "parse.go");
|
|
406
|
-
await fs.writeFile(scriptPath, GO_PARSE_SCRIPT, "utf8");
|
|
407
|
-
_cachedGoScriptPath = scriptPath;
|
|
408
|
-
}
|
|
409
|
-
const goBinary = resolveWin32Command("go");
|
|
410
|
-
const goResult = await new Promise(
|
|
411
|
-
(resolve, reject) => {
|
|
412
|
-
let settled = false;
|
|
413
|
-
recordParserSubprocess();
|
|
414
|
-
const proc = spawn(goBinary, ["run", scriptPath], {
|
|
415
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
416
|
-
windowsHide: true
|
|
417
|
-
});
|
|
418
|
-
proc.on("error", (err) => {
|
|
419
|
-
if (settled) return;
|
|
420
|
-
settled = true;
|
|
421
|
-
reject(err);
|
|
422
|
-
});
|
|
423
|
-
let stdout2 = "";
|
|
424
|
-
const stdoutDecoder = new StringDecoder("utf8");
|
|
425
|
-
proc.stdout?.on("data", (chunk) => {
|
|
426
|
-
stdout2 += stdoutDecoder.write(chunk);
|
|
427
|
-
});
|
|
428
|
-
proc.stderr?.resume();
|
|
429
|
-
proc.stdin?.write(content);
|
|
430
|
-
proc.stdin?.end();
|
|
431
|
-
const timer = setTimeout(() => {
|
|
432
|
-
if (settled) return;
|
|
433
|
-
settled = true;
|
|
434
|
-
proc.kill("SIGKILL");
|
|
435
|
-
reject(new Error("timeout"));
|
|
436
|
-
}, 15e3);
|
|
437
|
-
timer.unref?.();
|
|
438
|
-
proc.on("close", (code2) => {
|
|
439
|
-
if (settled) return;
|
|
440
|
-
settled = true;
|
|
441
|
-
clearTimeout(timer);
|
|
442
|
-
stdout2 += stdoutDecoder.end();
|
|
443
|
-
resolve({ code: code2, stdout: stdout2 });
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
);
|
|
447
|
-
const { code, stdout } = goResult;
|
|
448
|
-
if (code !== 0 || !stdout.trim()) {
|
|
449
|
-
return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
|
|
450
|
-
}
|
|
451
|
-
const { symbols: rawSymbols, refs } = parseParserOutput(stdout, lang);
|
|
452
|
-
const symbols = rawSymbols.map((s) => ({
|
|
453
|
-
id: 0,
|
|
454
|
-
lang,
|
|
455
|
-
kind: s.kind,
|
|
456
|
-
name: s.name,
|
|
457
|
-
file: filePath,
|
|
458
|
-
line: s.line,
|
|
459
|
-
col: s.col,
|
|
460
|
-
signature: s.signature ?? "",
|
|
461
|
-
docComment: "",
|
|
462
|
-
scope: s.scope ?? "",
|
|
463
|
-
text: `${s.name} ${s.signature ?? ""}`.trim()
|
|
464
|
-
}));
|
|
465
|
-
return { file: filePath, lang, symbols, refs, mtimeMs: Date.now() };
|
|
466
|
-
} catch {
|
|
467
|
-
return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
export {
|
|
471
|
-
detectLang,
|
|
472
|
-
parseSymbols
|
|
473
|
-
};
|
|
474
|
-
//# sourceMappingURL=go-parser-Z4H6SR3R.js.map
|