@wrongstack/tools 0.7.7 → 0.8.0
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 +208 -155
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.js +218 -164
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/index.js +208 -155
- package/dist/index.js.map +1 -1
- package/dist/pack.js +208 -155
- package/dist/pack.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as fs2 from 'node:fs/promises';
|
|
2
|
-
import * as
|
|
2
|
+
import * as path4 from 'node:path';
|
|
3
3
|
import { compileGlob } from '@wrongstack/core';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
4
5
|
import * as fs from 'node:fs';
|
|
5
|
-
import { mkdirSync, writeFileSync
|
|
6
|
-
import { DatabaseSync } from 'node:sqlite';
|
|
6
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
7
7
|
import * as ts from 'typescript';
|
|
8
8
|
import { execSync, spawnSync } from 'node:child_process';
|
|
9
|
+
import * as os from 'node:os';
|
|
9
10
|
|
|
10
11
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
11
12
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
@@ -82,12 +83,39 @@ function internalKindToLspKind(k) {
|
|
|
82
83
|
// src/codebase-index/writer.ts
|
|
83
84
|
var INDEX_DIR = ".codebase-index";
|
|
84
85
|
var DB_FILE = "index.db";
|
|
86
|
+
var warningSilenced = false;
|
|
87
|
+
function silenceSqliteExperimentalWarning() {
|
|
88
|
+
if (warningSilenced) return;
|
|
89
|
+
warningSilenced = true;
|
|
90
|
+
const original = process.emitWarning.bind(process);
|
|
91
|
+
process.emitWarning = ((warning, ...rest) => {
|
|
92
|
+
const msg = typeof warning === "string" ? warning : warning?.message ?? "";
|
|
93
|
+
const name = typeof warning === "string" ? String(rest[0] ?? "") : warning?.name ?? "";
|
|
94
|
+
if (/sqlite/i.test(msg) && /experimental/i.test(`${name} ${msg}`)) return;
|
|
95
|
+
original(warning, ...rest);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
var DatabaseSyncCtor;
|
|
99
|
+
function loadDatabaseSync() {
|
|
100
|
+
if (DatabaseSyncCtor) return DatabaseSyncCtor;
|
|
101
|
+
silenceSqliteExperimentalWarning();
|
|
102
|
+
try {
|
|
103
|
+
const req = createRequire(import.meta.url);
|
|
104
|
+
DatabaseSyncCtor = req("node:sqlite").DatabaseSync;
|
|
105
|
+
} catch (err) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`The codebase index needs Node's built-in SQLite (node:sqlite), available since Node 22.5. This runtime doesn't provide it: ${err instanceof Error ? err.message : String(err)}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return DatabaseSyncCtor;
|
|
111
|
+
}
|
|
85
112
|
var IndexStore = class {
|
|
86
113
|
constructor(projectRoot) {
|
|
87
114
|
this.projectRoot = projectRoot;
|
|
88
|
-
const dir =
|
|
115
|
+
const dir = path4.join(projectRoot, INDEX_DIR);
|
|
89
116
|
fs.mkdirSync(dir, { recursive: true });
|
|
90
|
-
|
|
117
|
+
const Database = loadDatabaseSync();
|
|
118
|
+
this.db = new Database(path4.join(dir, DB_FILE));
|
|
91
119
|
this.initSchema();
|
|
92
120
|
}
|
|
93
121
|
projectRoot;
|
|
@@ -282,7 +310,7 @@ var IndexStore = class {
|
|
|
282
310
|
totalFiles,
|
|
283
311
|
byLang,
|
|
284
312
|
byKind,
|
|
285
|
-
indexPath:
|
|
313
|
+
indexPath: path4.join(this.projectRoot, INDEX_DIR),
|
|
286
314
|
lastIndexed,
|
|
287
315
|
sizeBytes,
|
|
288
316
|
version: SCHEMA_VERSION
|
|
@@ -375,7 +403,7 @@ var IndexStore = class {
|
|
|
375
403
|
}));
|
|
376
404
|
}
|
|
377
405
|
sizeBytes() {
|
|
378
|
-
const dbPath =
|
|
406
|
+
const dbPath = path4.join(this.projectRoot, INDEX_DIR, DB_FILE);
|
|
379
407
|
try {
|
|
380
408
|
return fs.statSync(dbPath).size;
|
|
381
409
|
} catch {
|
|
@@ -590,6 +618,7 @@ import (
|
|
|
590
618
|
"go/ast"
|
|
591
619
|
"go/parser"
|
|
592
620
|
"go/token"
|
|
621
|
+
"io"
|
|
593
622
|
"os"
|
|
594
623
|
"strings"
|
|
595
624
|
)
|
|
@@ -604,17 +633,13 @@ type Sym struct {
|
|
|
604
633
|
}
|
|
605
634
|
|
|
606
635
|
func main() {
|
|
607
|
-
|
|
608
|
-
fmt.Print("[]")
|
|
609
|
-
return
|
|
610
|
-
}
|
|
611
|
-
src, err := os.ReadFile(os.Args[1])
|
|
636
|
+
src, err := io.ReadAll(os.Stdin)
|
|
612
637
|
if err != nil {
|
|
613
638
|
fmt.Print("[]")
|
|
614
639
|
return
|
|
615
640
|
}
|
|
616
641
|
fset := token.NewFileSet()
|
|
617
|
-
node, err := parser.ParseFile(fset,
|
|
642
|
+
node, err := parser.ParseFile(fset, "src.go", src, 0)
|
|
618
643
|
if err != nil {
|
|
619
644
|
fmt.Print("[]")
|
|
620
645
|
return
|
|
@@ -758,7 +783,7 @@ func formatMethods(fields []*ast.Field) string {
|
|
|
758
783
|
return formatFields(fields)
|
|
759
784
|
}
|
|
760
785
|
|
|
761
|
-
func formatTypeParams(tp *ast.
|
|
786
|
+
func formatTypeParams(tp *ast.FieldList) string {
|
|
762
787
|
if tp == nil || len(tp.List) == 0 {
|
|
763
788
|
return ""
|
|
764
789
|
}
|
|
@@ -801,30 +826,33 @@ func formatType(t ast.Expr) string {
|
|
|
801
826
|
return "chan " + formatType(v.Value)
|
|
802
827
|
case *ast.BasicLit:
|
|
803
828
|
return v.Value
|
|
829
|
+
case *ast.IndexExpr:
|
|
830
|
+
// Generic instantiation with one type arg, e.g. Logger[int].
|
|
831
|
+
return formatType(v.X) + "[" + formatType(v.Index) + "]"
|
|
832
|
+
case *ast.IndexListExpr:
|
|
833
|
+
// Generic instantiation with multiple type args, e.g. Map[K, V].
|
|
834
|
+
args := make([]string, len(v.Indices))
|
|
835
|
+
for i, idx := range v.Indices {
|
|
836
|
+
args[i] = formatType(idx)
|
|
837
|
+
}
|
|
838
|
+
return formatType(v.X) + "[" + strings.Join(args, ", ") + "]"
|
|
804
839
|
default:
|
|
805
840
|
return "?"
|
|
806
841
|
}
|
|
807
842
|
}
|
|
808
843
|
`;
|
|
809
|
-
function syncGoParse(filePath,
|
|
810
|
-
const tmpDir =
|
|
844
|
+
function syncGoParse(filePath, content, lang) {
|
|
845
|
+
const tmpDir = path4.join(os.tmpdir(), "ws-go-parse");
|
|
811
846
|
try {
|
|
812
847
|
mkdirSync(tmpDir, { recursive: true });
|
|
813
|
-
const scriptPath =
|
|
848
|
+
const scriptPath = path4.join(tmpDir, "parse.go");
|
|
814
849
|
writeFileSync(scriptPath, GO_PARSE_SCRIPT, "utf8");
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
});
|
|
822
|
-
} finally {
|
|
823
|
-
try {
|
|
824
|
-
unlinkSync(scriptPath);
|
|
825
|
-
} catch {
|
|
826
|
-
}
|
|
827
|
-
}
|
|
850
|
+
const stdout = execSync(`go run "${scriptPath}"`, {
|
|
851
|
+
input: content,
|
|
852
|
+
timeout: 15e3,
|
|
853
|
+
encoding: "utf8",
|
|
854
|
+
windowsHide: true
|
|
855
|
+
});
|
|
828
856
|
if (!stdout.trim()) {
|
|
829
857
|
return { file: filePath, lang, symbols: [], mtimeMs: Date.now() };
|
|
830
858
|
}
|
|
@@ -1061,7 +1089,11 @@ print(json.dumps([s.to_dict() for s in syms]))
|
|
|
1061
1089
|
`;
|
|
1062
1090
|
function syncPyParse(filePath, lang) {
|
|
1063
1091
|
try {
|
|
1064
|
-
const
|
|
1092
|
+
const tmpDir = path4.join(os.tmpdir(), "ws-py-parse");
|
|
1093
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
1094
|
+
const scriptPath = path4.join(tmpDir, "parse.py");
|
|
1095
|
+
writeFileSync(scriptPath, PY_PARSE_SCRIPT, "utf8");
|
|
1096
|
+
const stdout = execSync(`python "${scriptPath}" "${filePath}"`, {
|
|
1065
1097
|
timeout: 15e3,
|
|
1066
1098
|
encoding: "utf8",
|
|
1067
1099
|
windowsHide: true
|
|
@@ -1100,9 +1132,12 @@ function parseSymbols4(opts) {
|
|
|
1100
1132
|
function checkNativeParser() {
|
|
1101
1133
|
try {
|
|
1102
1134
|
execSync("rustc --version", { stdio: "pipe" });
|
|
1103
|
-
const toolsDir =
|
|
1135
|
+
const toolsDir = path4.join(process.cwd(), "tools");
|
|
1104
1136
|
try {
|
|
1105
|
-
execSync(
|
|
1137
|
+
execSync(
|
|
1138
|
+
"cargo metadata --no-deps --format-version 1 --manifest-path " + path4.join(toolsDir, "Cargo.toml"),
|
|
1139
|
+
{ stdio: "pipe" }
|
|
1140
|
+
);
|
|
1106
1141
|
return true;
|
|
1107
1142
|
} catch {
|
|
1108
1143
|
return false;
|
|
@@ -1113,17 +1148,21 @@ function checkNativeParser() {
|
|
|
1113
1148
|
}
|
|
1114
1149
|
function tryNativeParse(file, content) {
|
|
1115
1150
|
try {
|
|
1116
|
-
const toolsDir =
|
|
1117
|
-
const crateDir =
|
|
1118
|
-
const tmpFile =
|
|
1119
|
-
const { writeFileSync:
|
|
1120
|
-
|
|
1121
|
-
const result = spawnSync(
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1151
|
+
const toolsDir = path4.join(process.cwd(), "tools");
|
|
1152
|
+
const crateDir = path4.join(toolsDir, "syn-parser");
|
|
1153
|
+
const tmpFile = path4.join(crateDir, "src", "input.rs");
|
|
1154
|
+
const { writeFileSync: writeFileSync3 } = __require("node:fs");
|
|
1155
|
+
writeFileSync3(tmpFile, content, "utf8");
|
|
1156
|
+
const result = spawnSync(
|
|
1157
|
+
"cargo",
|
|
1158
|
+
["run", "--manifest-path", path4.join(toolsDir, "Cargo.toml")],
|
|
1159
|
+
{
|
|
1160
|
+
cwd: process.cwd(),
|
|
1161
|
+
encoding: "utf8",
|
|
1162
|
+
timeout: 15e3,
|
|
1163
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1164
|
+
}
|
|
1165
|
+
);
|
|
1127
1166
|
if (result.status === 0 && result.stdout) {
|
|
1128
1167
|
const symbols = JSON.parse(result.stdout);
|
|
1129
1168
|
return {
|
|
@@ -1157,7 +1196,8 @@ function regexParse(opts) {
|
|
|
1157
1196
|
lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
|
|
1158
1197
|
}
|
|
1159
1198
|
function lineFromOffset(offset) {
|
|
1160
|
-
let lo = 0
|
|
1199
|
+
let lo = 0;
|
|
1200
|
+
let hi = lineOffsets.length - 1;
|
|
1161
1201
|
while (lo < hi) {
|
|
1162
1202
|
const mid = lo + hi + 1 >>> 1;
|
|
1163
1203
|
if (lineOffsets[mid] <= offset) lo = mid;
|
|
@@ -1171,8 +1211,7 @@ function regexParse(opts) {
|
|
|
1171
1211
|
}
|
|
1172
1212
|
for (const pattern of RS_PATTERNS) {
|
|
1173
1213
|
pattern.regex.lastIndex = 0;
|
|
1174
|
-
let match;
|
|
1175
|
-
while ((match = pattern.regex.exec(content)) !== null) {
|
|
1214
|
+
for (let match = pattern.regex.exec(content); match !== null; match = pattern.regex.exec(content)) {
|
|
1176
1215
|
const name = match[1];
|
|
1177
1216
|
const offset = match.index;
|
|
1178
1217
|
const line = lineFromOffset(offset);
|
|
@@ -1214,7 +1253,7 @@ function parseSymbols5(opts) {
|
|
|
1214
1253
|
function regexParse2(opts) {
|
|
1215
1254
|
const { file, content, lang } = opts;
|
|
1216
1255
|
const symbols = [];
|
|
1217
|
-
const basename2 =
|
|
1256
|
+
const basename2 = path4.basename(file).toLowerCase();
|
|
1218
1257
|
const isPackageJson = basename2 === "package.json";
|
|
1219
1258
|
const isTsconfig = basename2 === "tsconfig.json" || basename2 === "tsconfig.build.json";
|
|
1220
1259
|
const isJsonSchema = content.includes("$schema") || content.includes("$id") || content.includes("$ref");
|
|
@@ -1225,7 +1264,8 @@ function regexParse2(opts) {
|
|
|
1225
1264
|
lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
|
|
1226
1265
|
}
|
|
1227
1266
|
function lineFromOffset(offset) {
|
|
1228
|
-
let lo = 0
|
|
1267
|
+
let lo = 0;
|
|
1268
|
+
let hi = lineOffsets.length - 1;
|
|
1229
1269
|
while (lo < hi) {
|
|
1230
1270
|
const mid = lo + hi + 1 >>> 1;
|
|
1231
1271
|
if (lineOffsets[mid] <= offset) lo = mid;
|
|
@@ -1237,19 +1277,20 @@ function regexParse2(opts) {
|
|
|
1237
1277
|
if (rootMatch) {
|
|
1238
1278
|
const offset = rootMatch.index;
|
|
1239
1279
|
const line = lineFromOffset(offset);
|
|
1240
|
-
symbols.push(
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1280
|
+
symbols.push(
|
|
1281
|
+
makeSymbol({
|
|
1282
|
+
name: path4.basename(file),
|
|
1283
|
+
kind: "object",
|
|
1284
|
+
line,
|
|
1285
|
+
col: 0,
|
|
1286
|
+
signature: `"${path4.basename(file)}" = { ... }`,
|
|
1287
|
+
file,
|
|
1288
|
+
lang
|
|
1289
|
+
})
|
|
1290
|
+
);
|
|
1249
1291
|
}
|
|
1250
1292
|
const topLevelKeyRegex = /^\s*"([^"]+)"\s*:/gm;
|
|
1251
|
-
let match;
|
|
1252
|
-
while ((match = topLevelKeyRegex.exec(content)) !== null) {
|
|
1293
|
+
for (let match = topLevelKeyRegex.exec(content); match !== null; match = topLevelKeyRegex.exec(content)) {
|
|
1253
1294
|
const key = match[1];
|
|
1254
1295
|
const offset = match.index;
|
|
1255
1296
|
const line = lineFromOffset(offset);
|
|
@@ -1276,15 +1317,17 @@ function regexParse2(opts) {
|
|
|
1276
1317
|
signature = `"$ref": "..."`;
|
|
1277
1318
|
}
|
|
1278
1319
|
}
|
|
1279
|
-
symbols.push(
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1320
|
+
symbols.push(
|
|
1321
|
+
makeSymbol({
|
|
1322
|
+
name: key,
|
|
1323
|
+
kind,
|
|
1324
|
+
line,
|
|
1325
|
+
col,
|
|
1326
|
+
signature,
|
|
1327
|
+
file,
|
|
1328
|
+
lang
|
|
1329
|
+
})
|
|
1330
|
+
);
|
|
1288
1331
|
if (isPackageJson && key === "scripts") {
|
|
1289
1332
|
extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset);
|
|
1290
1333
|
}
|
|
@@ -1293,20 +1336,21 @@ function regexParse2(opts) {
|
|
|
1293
1336
|
}
|
|
1294
1337
|
}
|
|
1295
1338
|
const defsRegex = /"\$defs"\s*:|"\$defs"\s*:/g;
|
|
1296
|
-
|
|
1297
|
-
|
|
1339
|
+
const defsMatch = defsRegex.exec(content);
|
|
1340
|
+
if (defsMatch !== null) {
|
|
1298
1341
|
const offset = defsMatch.index;
|
|
1299
1342
|
const line = lineFromOffset(offset);
|
|
1300
|
-
symbols.push(
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1343
|
+
symbols.push(
|
|
1344
|
+
makeSymbol({
|
|
1345
|
+
name: "$defs",
|
|
1346
|
+
kind: "property",
|
|
1347
|
+
line,
|
|
1348
|
+
col: offset - (lineOffsets[line - 1] ?? 0),
|
|
1349
|
+
signature: '"$defs": { ... }',
|
|
1350
|
+
file,
|
|
1351
|
+
lang
|
|
1352
|
+
})
|
|
1353
|
+
);
|
|
1310
1354
|
}
|
|
1311
1355
|
const defsPatterns = [
|
|
1312
1356
|
/"\$defs"\s*:/g,
|
|
@@ -1316,69 +1360,71 @@ function regexParse2(opts) {
|
|
|
1316
1360
|
];
|
|
1317
1361
|
for (const pat of defsPatterns) {
|
|
1318
1362
|
pat.lastIndex = 0;
|
|
1319
|
-
|
|
1363
|
+
for (let match = pat.exec(content); match !== null; match = pat.exec(content)) {
|
|
1320
1364
|
const offset = match.index;
|
|
1321
1365
|
const line = lineFromOffset(offset);
|
|
1322
1366
|
const key = match[0].match(/"([^"]+)"/)?.[1] ?? match[0];
|
|
1323
|
-
symbols.push(
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1367
|
+
symbols.push(
|
|
1368
|
+
makeSymbol({
|
|
1369
|
+
name: key,
|
|
1370
|
+
kind: "property",
|
|
1371
|
+
line,
|
|
1372
|
+
col: offset - (lineOffsets[line - 1] ?? 0),
|
|
1373
|
+
signature: `"${key}": { ... }`,
|
|
1374
|
+
file,
|
|
1375
|
+
lang
|
|
1376
|
+
})
|
|
1377
|
+
);
|
|
1332
1378
|
}
|
|
1333
1379
|
}
|
|
1334
1380
|
return { file, lang, symbols, mtimeMs: Date.now() };
|
|
1335
1381
|
}
|
|
1336
1382
|
function extractPackageScripts(content, symbols, file, lang, lineOffsets, lineFromOffset) {
|
|
1337
1383
|
const scriptsBlockRegex = /"scripts"\s*:\s*\{([^}]+)\}/g;
|
|
1338
|
-
let match;
|
|
1339
|
-
while ((match = scriptsBlockRegex.exec(content)) !== null) {
|
|
1384
|
+
for (let match = scriptsBlockRegex.exec(content); match !== null; match = scriptsBlockRegex.exec(content)) {
|
|
1340
1385
|
const blockContent = match[0];
|
|
1341
1386
|
const blockOffset = match.index;
|
|
1342
1387
|
const scriptKeyRegex = /"(\w[\w-]*)"\s*:/g;
|
|
1343
|
-
let scriptMatch;
|
|
1344
|
-
while ((scriptMatch = scriptKeyRegex.exec(blockContent)) !== null) {
|
|
1388
|
+
for (let scriptMatch = scriptKeyRegex.exec(blockContent); scriptMatch !== null; scriptMatch = scriptKeyRegex.exec(blockContent)) {
|
|
1345
1389
|
const key = scriptMatch[1];
|
|
1346
1390
|
const keyOffset = blockOffset + scriptMatch.index;
|
|
1347
1391
|
const line = lineFromOffset(keyOffset);
|
|
1348
|
-
symbols.push(
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1392
|
+
symbols.push(
|
|
1393
|
+
makeSymbol({
|
|
1394
|
+
name: key,
|
|
1395
|
+
kind: "function",
|
|
1396
|
+
line,
|
|
1397
|
+
col: keyOffset - (lineOffsets[line - 1] ?? 0),
|
|
1398
|
+
signature: `"${key}": "..."`,
|
|
1399
|
+
file,
|
|
1400
|
+
lang
|
|
1401
|
+
})
|
|
1402
|
+
);
|
|
1357
1403
|
}
|
|
1358
1404
|
}
|
|
1359
1405
|
}
|
|
1360
1406
|
function extractCompilerOptions(content, symbols, file, lang, lineOffsets, parentLine, lineFromOffset) {
|
|
1361
1407
|
const optsBlockRegex = /"compilerOptions"\s*:\s*\{([^}]+)\}/g;
|
|
1362
|
-
let match;
|
|
1363
|
-
while ((match = optsBlockRegex.exec(content)) !== null) {
|
|
1408
|
+
for (let match = optsBlockRegex.exec(content); match !== null; match = optsBlockRegex.exec(content)) {
|
|
1364
1409
|
const blockContent = match[0];
|
|
1365
1410
|
const blockOffset = match.index;
|
|
1366
1411
|
const optKeyRegex = /"(\w[\w]*)"\s*:/g;
|
|
1367
|
-
let optMatch;
|
|
1368
|
-
while ((optMatch = optKeyRegex.exec(blockContent)) !== null) {
|
|
1412
|
+
for (let optMatch = optKeyRegex.exec(blockContent); optMatch !== null; optMatch = optKeyRegex.exec(blockContent)) {
|
|
1369
1413
|
const key = optMatch[1];
|
|
1370
1414
|
const keyOffset = blockOffset + optMatch.index;
|
|
1371
1415
|
const line = lineFromOffset(keyOffset);
|
|
1372
1416
|
if (line <= parentLine) continue;
|
|
1373
|
-
symbols.push(
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1417
|
+
symbols.push(
|
|
1418
|
+
makeSymbol({
|
|
1419
|
+
name: key,
|
|
1420
|
+
kind: "property",
|
|
1421
|
+
line,
|
|
1422
|
+
col: keyOffset - (lineOffsets[line - 1] ?? 0),
|
|
1423
|
+
signature: `"${key}": ...`,
|
|
1424
|
+
file,
|
|
1425
|
+
lang
|
|
1426
|
+
})
|
|
1427
|
+
);
|
|
1382
1428
|
}
|
|
1383
1429
|
}
|
|
1384
1430
|
}
|
|
@@ -1416,7 +1462,8 @@ function regexParse3(opts) {
|
|
|
1416
1462
|
lineOffsets.push(lineOffsets[i] + lines[i].length + 1);
|
|
1417
1463
|
}
|
|
1418
1464
|
function lineFromOffset(offset) {
|
|
1419
|
-
let lo = 0
|
|
1465
|
+
let lo = 0;
|
|
1466
|
+
let hi = lineOffsets.length - 1;
|
|
1420
1467
|
while (lo < hi) {
|
|
1421
1468
|
const mid = lo + hi + 1 >>> 1;
|
|
1422
1469
|
if (lineOffsets[mid] <= offset) lo = mid;
|
|
@@ -1425,40 +1472,43 @@ function regexParse3(opts) {
|
|
|
1425
1472
|
return lo + 1;
|
|
1426
1473
|
}
|
|
1427
1474
|
const anchorRegex = /&(\w[\w-]*)/g;
|
|
1428
|
-
let match;
|
|
1429
|
-
while ((match = anchorRegex.exec(content)) !== null) {
|
|
1475
|
+
for (let match = anchorRegex.exec(content); match !== null; match = anchorRegex.exec(content)) {
|
|
1430
1476
|
const name = match[1];
|
|
1431
1477
|
const offset = match.index;
|
|
1432
1478
|
const line = lineFromOffset(offset);
|
|
1433
1479
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1434
|
-
symbols.push(
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1480
|
+
symbols.push(
|
|
1481
|
+
makeSymbol2({
|
|
1482
|
+
name,
|
|
1483
|
+
kind: "const",
|
|
1484
|
+
line,
|
|
1485
|
+
col,
|
|
1486
|
+
signature: `&${name}`,
|
|
1487
|
+
file,
|
|
1488
|
+
lang
|
|
1489
|
+
})
|
|
1490
|
+
);
|
|
1443
1491
|
}
|
|
1444
1492
|
const aliasRegex = /\*(\w[\w-]*)/g;
|
|
1445
|
-
|
|
1493
|
+
for (let match = aliasRegex.exec(content); match !== null; match = aliasRegex.exec(content)) {
|
|
1446
1494
|
const name = match[1];
|
|
1447
1495
|
const offset = match.index;
|
|
1448
1496
|
const line = lineFromOffset(offset);
|
|
1449
1497
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1450
|
-
symbols.push(
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1498
|
+
symbols.push(
|
|
1499
|
+
makeSymbol2({
|
|
1500
|
+
name,
|
|
1501
|
+
kind: "const",
|
|
1502
|
+
line,
|
|
1503
|
+
col,
|
|
1504
|
+
signature: `*${name}`,
|
|
1505
|
+
file,
|
|
1506
|
+
lang
|
|
1507
|
+
})
|
|
1508
|
+
);
|
|
1459
1509
|
}
|
|
1460
1510
|
const kvRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:/gm;
|
|
1461
|
-
|
|
1511
|
+
for (let match = kvRegex.exec(content); match !== null; match = kvRegex.exec(content)) {
|
|
1462
1512
|
const indent = match[1].length;
|
|
1463
1513
|
const key = match[2];
|
|
1464
1514
|
const offset = match.index;
|
|
@@ -1474,38 +1524,42 @@ function regexParse3(opts) {
|
|
|
1474
1524
|
symbols.push(makeSymbol2({ name: key, kind, line, col, signature, file, lang }));
|
|
1475
1525
|
}
|
|
1476
1526
|
const listItemRegex = /^-(\s+)([^:#\s][^:#\s]*)\s*:/gm;
|
|
1477
|
-
|
|
1527
|
+
for (let match = listItemRegex.exec(content); match !== null; match = listItemRegex.exec(content)) {
|
|
1478
1528
|
const key = match[2];
|
|
1479
1529
|
const offset = match.index;
|
|
1480
1530
|
const line = lineFromOffset(offset);
|
|
1481
1531
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1482
1532
|
const value = extractValue(content, offset + match[0].length);
|
|
1483
1533
|
const kind = isScalar(value) ? "literal" : "property";
|
|
1484
|
-
symbols.push(
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1534
|
+
symbols.push(
|
|
1535
|
+
makeSymbol2({
|
|
1536
|
+
name: key,
|
|
1537
|
+
kind,
|
|
1538
|
+
line,
|
|
1539
|
+
col,
|
|
1540
|
+
signature: `- ${key}: ${truncate(value, 60)}`,
|
|
1541
|
+
file,
|
|
1542
|
+
lang
|
|
1543
|
+
})
|
|
1544
|
+
);
|
|
1493
1545
|
}
|
|
1494
1546
|
const blockScalarRegex = /^(\s*)([^:#\s][^:#\s]*)\s*:\s*[|>](\s|$)/gm;
|
|
1495
|
-
|
|
1547
|
+
for (let match = blockScalarRegex.exec(content); match !== null; match = blockScalarRegex.exec(content)) {
|
|
1496
1548
|
const key = match[2];
|
|
1497
1549
|
const offset = match.index;
|
|
1498
1550
|
const line = lineFromOffset(offset);
|
|
1499
1551
|
const col = offset - (lineOffsets[line - 1] ?? 0);
|
|
1500
|
-
symbols.push(
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1552
|
+
symbols.push(
|
|
1553
|
+
makeSymbol2({
|
|
1554
|
+
name: key,
|
|
1555
|
+
kind: "property",
|
|
1556
|
+
line,
|
|
1557
|
+
col,
|
|
1558
|
+
signature: `${key}: | ...`,
|
|
1559
|
+
file,
|
|
1560
|
+
lang
|
|
1561
|
+
})
|
|
1562
|
+
);
|
|
1509
1563
|
}
|
|
1510
1564
|
return { file, lang, symbols, mtimeMs: Date.now() };
|
|
1511
1565
|
}
|
|
@@ -1577,12 +1631,12 @@ async function findSourceFiles(projectRoot, ignore) {
|
|
|
1577
1631
|
}
|
|
1578
1632
|
for (const e of entries) {
|
|
1579
1633
|
if (ignoreSet.has(e.name)) continue;
|
|
1580
|
-
const full =
|
|
1634
|
+
const full = path4.join(dir, e.name);
|
|
1581
1635
|
if (e.isDirectory()) {
|
|
1582
1636
|
await walk(full);
|
|
1583
1637
|
} else if (e.isFile()) {
|
|
1584
|
-
const rel =
|
|
1585
|
-
const ext =
|
|
1638
|
+
const rel = path4.relative(projectRoot, full).replace(/\\/g, "/");
|
|
1639
|
+
const ext = path4.extname(e.name);
|
|
1586
1640
|
for (const { ext: extName, pat } of globs) {
|
|
1587
1641
|
if (ext === extName && (pat.test(rel) || pat.test(e.name))) {
|
|
1588
1642
|
results.push(full);
|
|
@@ -1626,7 +1680,7 @@ async function runIndexer(ctx, opts) {
|
|
|
1626
1680
|
let symbolsIndexed = 0;
|
|
1627
1681
|
let files;
|
|
1628
1682
|
if (opts.files && opts.files.length > 0) {
|
|
1629
|
-
files = opts.files.map((f) =>
|
|
1683
|
+
files = opts.files.map((f) => path4.resolve(projectRoot, f));
|
|
1630
1684
|
} else {
|
|
1631
1685
|
files = await findSourceFiles(projectRoot, ignore);
|
|
1632
1686
|
}
|