@buildautomaton/cli 0.1.67 → 0.1.69
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/cli.js +26439 -23953
- package/dist/cli.js.map +4 -4
- package/dist/index.js +10815 -8323
- package/dist/index.js.map +4 -4
- package/dist/symbol-index-worker.js +4609 -0
- package/dist/symbol-index-worker.js.map +7 -0
- package/dist/worker.js +5166 -0
- package/dist/worker.js.map +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,4609 @@
|
|
|
1
|
+
import { createRequire } from "module"; const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
12
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
13
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
|
|
32
|
+
// src/runtime/cli-process-interrupt.ts
|
|
33
|
+
function isCliImmediateShutdownRequested() {
|
|
34
|
+
return cliImmediateShutdownRequested;
|
|
35
|
+
}
|
|
36
|
+
var cliImmediateShutdownRequested;
|
|
37
|
+
var init_cli_process_interrupt = __esm({
|
|
38
|
+
"src/runtime/cli-process-interrupt.ts"() {
|
|
39
|
+
"use strict";
|
|
40
|
+
cliImmediateShutdownRequested = false;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// src/paths/normalize-resolved-path.ts
|
|
45
|
+
import fs from "node:fs";
|
|
46
|
+
import path from "node:path";
|
|
47
|
+
function normalizeResolvedPath(resolved) {
|
|
48
|
+
const abs = path.resolve(resolved);
|
|
49
|
+
try {
|
|
50
|
+
return fs.realpathSync.native(abs);
|
|
51
|
+
} catch {
|
|
52
|
+
return abs;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
var init_normalize_resolved_path = __esm({
|
|
56
|
+
"src/paths/normalize-resolved-path.ts"() {
|
|
57
|
+
"use strict";
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// src/runtime/yield-to-event-loop.ts
|
|
62
|
+
function yieldToEventLoop() {
|
|
63
|
+
return new Promise((resolve) => setImmediate(resolve));
|
|
64
|
+
}
|
|
65
|
+
var init_yield_to_event_loop = __esm({
|
|
66
|
+
"src/runtime/yield-to-event-loop.ts"() {
|
|
67
|
+
"use strict";
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// src/sqlite/sqlite-errors.ts
|
|
72
|
+
function isCliSqliteLockError(e) {
|
|
73
|
+
if (e instanceof CliSqliteInterrupted) return false;
|
|
74
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
75
|
+
const lower = msg.toLowerCase();
|
|
76
|
+
return lower.includes("database is locked") || lower.includes("sqlite_busy") || lower.includes("sqlite3_busy") || lower.includes("database") && lower.includes("locked");
|
|
77
|
+
}
|
|
78
|
+
var CliSqliteInterrupted;
|
|
79
|
+
var init_sqlite_errors = __esm({
|
|
80
|
+
"src/sqlite/sqlite-errors.ts"() {
|
|
81
|
+
"use strict";
|
|
82
|
+
CliSqliteInterrupted = class extends Error {
|
|
83
|
+
name = "CliSqliteInterrupted";
|
|
84
|
+
constructor() {
|
|
85
|
+
super("CLI SQLite interrupted (shutdown)");
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// src/sqlite/sqlite-pragmas.ts
|
|
92
|
+
function applySqliteConcurrencyPragmas(db) {
|
|
93
|
+
try {
|
|
94
|
+
db.run("PRAGMA foreign_keys = ON");
|
|
95
|
+
} catch {
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
db.exec("PRAGMA journal_mode = WAL");
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
db.run("PRAGMA synchronous = NORMAL");
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
db.run("PRAGMA busy_timeout = 500");
|
|
107
|
+
} catch {
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function applySqliteMemoryPragmas(db) {
|
|
111
|
+
try {
|
|
112
|
+
db.run("PRAGMA cache_size = -8192");
|
|
113
|
+
db.run("PRAGMA temp_store = FILE");
|
|
114
|
+
} catch {
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
var init_sqlite_pragmas = __esm({
|
|
118
|
+
"src/sqlite/sqlite-pragmas.ts"() {
|
|
119
|
+
"use strict";
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// src/sqlite/sqlite-lock-retry.ts
|
|
124
|
+
function syncSleepMs(ms) {
|
|
125
|
+
if (ms <= 0) return;
|
|
126
|
+
const deadline = Date.now() + ms;
|
|
127
|
+
while (Date.now() < deadline) {
|
|
128
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
129
|
+
const chunk = Math.min(10, deadline - Date.now());
|
|
130
|
+
if (chunk <= 0) break;
|
|
131
|
+
try {
|
|
132
|
+
const sab = new SharedArrayBuffer(4);
|
|
133
|
+
const ia = new Int32Array(sab);
|
|
134
|
+
Atomics.wait(ia, 0, 0, chunk);
|
|
135
|
+
} catch {
|
|
136
|
+
const end = Date.now() + chunk;
|
|
137
|
+
while (Date.now() < end) {
|
|
138
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function asyncDelayMsInterruptible(ms) {
|
|
144
|
+
const end = Date.now() + ms;
|
|
145
|
+
while (Date.now() < end) {
|
|
146
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
147
|
+
const chunk = Math.min(50, end - Date.now());
|
|
148
|
+
if (chunk <= 0) break;
|
|
149
|
+
await new Promise((r) => setTimeout(r, chunk));
|
|
150
|
+
await yieldToEventLoop();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
var SYNC_RETRY_MAX, ASYNC_RETRY_MAX, ASYNC_BASE_DELAY_MS;
|
|
154
|
+
var init_sqlite_lock_retry = __esm({
|
|
155
|
+
"src/sqlite/sqlite-lock-retry.ts"() {
|
|
156
|
+
"use strict";
|
|
157
|
+
init_cli_process_interrupt();
|
|
158
|
+
init_yield_to_event_loop();
|
|
159
|
+
init_sqlite_errors();
|
|
160
|
+
SYNC_RETRY_MAX = 40;
|
|
161
|
+
ASYNC_RETRY_MAX = 60;
|
|
162
|
+
ASYNC_BASE_DELAY_MS = 20;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// src/sqlite/create-sqlite-database-access.ts
|
|
167
|
+
import sqliteWasm from "node-sqlite3-wasm";
|
|
168
|
+
function createSqliteDatabaseAccess(config) {
|
|
169
|
+
let migrateDoneForPath = null;
|
|
170
|
+
function shouldSkipMigrate(sqlitePath, db) {
|
|
171
|
+
if (migrateDoneForPath !== sqlitePath) return false;
|
|
172
|
+
try {
|
|
173
|
+
const row = db.get(
|
|
174
|
+
"SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='__migrations' LIMIT 1"
|
|
175
|
+
);
|
|
176
|
+
return row != null;
|
|
177
|
+
} catch {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function safeClose(db) {
|
|
182
|
+
if (db == null) return;
|
|
183
|
+
try {
|
|
184
|
+
if (db.isOpen) db.close();
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function openConnection(options) {
|
|
189
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
190
|
+
const sqlitePath = config.getPath();
|
|
191
|
+
config.ensureParentDir(sqlitePath);
|
|
192
|
+
const db = new SqliteDatabase(sqlitePath);
|
|
193
|
+
try {
|
|
194
|
+
applySqliteConcurrencyPragmas(db);
|
|
195
|
+
applySqliteMemoryPragmas(db);
|
|
196
|
+
const sqlitePath2 = config.getPath();
|
|
197
|
+
if (!shouldSkipMigrate(sqlitePath2, db)) {
|
|
198
|
+
config.migrate(db);
|
|
199
|
+
migrateDoneForPath = sqlitePath2;
|
|
200
|
+
}
|
|
201
|
+
config.afterOpen?.(db, options);
|
|
202
|
+
} catch (e) {
|
|
203
|
+
safeClose(db);
|
|
204
|
+
throw e;
|
|
205
|
+
}
|
|
206
|
+
return db;
|
|
207
|
+
}
|
|
208
|
+
function withSync(fn, options) {
|
|
209
|
+
for (let attempt = 1; attempt <= SYNC_RETRY_MAX; attempt++) {
|
|
210
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
211
|
+
let db;
|
|
212
|
+
try {
|
|
213
|
+
db = openConnection(options);
|
|
214
|
+
try {
|
|
215
|
+
return fn(db);
|
|
216
|
+
} finally {
|
|
217
|
+
safeClose(db);
|
|
218
|
+
}
|
|
219
|
+
} catch (e) {
|
|
220
|
+
safeClose(db);
|
|
221
|
+
if (e instanceof CliSqliteInterrupted) throw e;
|
|
222
|
+
if (!isCliSqliteLockError(e) || attempt === SYNC_RETRY_MAX) throw e;
|
|
223
|
+
syncSleepMs(Math.min(500, 12 * attempt));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
throw new Error("withSqliteSync: exhausted retries");
|
|
227
|
+
}
|
|
228
|
+
async function withAsync(fn, options) {
|
|
229
|
+
let lastError;
|
|
230
|
+
for (let attempt = 1; attempt <= ASYNC_RETRY_MAX; attempt++) {
|
|
231
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
232
|
+
let db;
|
|
233
|
+
try {
|
|
234
|
+
db = openConnection(options);
|
|
235
|
+
try {
|
|
236
|
+
return await Promise.resolve(fn(db));
|
|
237
|
+
} finally {
|
|
238
|
+
safeClose(db);
|
|
239
|
+
}
|
|
240
|
+
} catch (e) {
|
|
241
|
+
lastError = e;
|
|
242
|
+
safeClose(db);
|
|
243
|
+
if (e instanceof CliSqliteInterrupted) throw e;
|
|
244
|
+
if (!isCliSqliteLockError(e) || attempt === ASYNC_RETRY_MAX) throw e;
|
|
245
|
+
const delayMs = Math.min(600, ASYNC_BASE_DELAY_MS * attempt);
|
|
246
|
+
await asyncDelayMsInterruptible(delayMs);
|
|
247
|
+
await yieldToEventLoop();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (lastError instanceof Error) throw lastError;
|
|
251
|
+
throw new Error(String(lastError));
|
|
252
|
+
}
|
|
253
|
+
async function ensureInitialized(options) {
|
|
254
|
+
await withAsync(() => void 0, options);
|
|
255
|
+
}
|
|
256
|
+
function closeAllConnections() {
|
|
257
|
+
migrateDoneForPath = null;
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
safeClose,
|
|
261
|
+
openConnection,
|
|
262
|
+
withSync,
|
|
263
|
+
withAsync,
|
|
264
|
+
ensureInitialized,
|
|
265
|
+
closeAllConnections
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
var SqliteDatabase;
|
|
269
|
+
var init_create_sqlite_database_access = __esm({
|
|
270
|
+
"src/sqlite/create-sqlite-database-access.ts"() {
|
|
271
|
+
"use strict";
|
|
272
|
+
init_yield_to_event_loop();
|
|
273
|
+
init_cli_process_interrupt();
|
|
274
|
+
init_sqlite_errors();
|
|
275
|
+
init_sqlite_pragmas();
|
|
276
|
+
init_sqlite_lock_retry();
|
|
277
|
+
({ Database: SqliteDatabase } = sqliteWasm);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// src/sqlite/code-nav-cache/code-nav-cache-paths.ts
|
|
282
|
+
import fs2 from "node:fs";
|
|
283
|
+
import path2 from "node:path";
|
|
284
|
+
import os from "node:os";
|
|
285
|
+
function getCodeNavCacheSqlitePath() {
|
|
286
|
+
const override = process.env.BUILDAMATON_CODE_NAV_CACHE_SQLITE_PATH?.trim();
|
|
287
|
+
if (override) return path2.resolve(override);
|
|
288
|
+
return path2.join(os.homedir(), ".buildautomaton", "code-nav-cache.sqlite");
|
|
289
|
+
}
|
|
290
|
+
function ensureCodeNavCacheSqliteParentDir(sqlitePath) {
|
|
291
|
+
const dir = path2.dirname(sqlitePath);
|
|
292
|
+
if (!fs2.existsSync(dir)) fs2.mkdirSync(dir, { recursive: true });
|
|
293
|
+
}
|
|
294
|
+
var init_code_nav_cache_paths = __esm({
|
|
295
|
+
"src/sqlite/code-nav-cache/code-nav-cache-paths.ts"() {
|
|
296
|
+
"use strict";
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// src/sqlite/read-migration-sql.ts
|
|
301
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
302
|
+
import { dirname, join } from "node:path";
|
|
303
|
+
import { fileURLToPath } from "node:url";
|
|
304
|
+
function readMigrationSql(filename, ...searchSubdirs) {
|
|
305
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
306
|
+
const candidates = searchSubdirs.flatMap((sub) => [
|
|
307
|
+
join(moduleDir, sub, filename),
|
|
308
|
+
join(moduleDir, "..", sub, filename),
|
|
309
|
+
join(moduleDir, "..", "..", "dist", sub, filename)
|
|
310
|
+
]);
|
|
311
|
+
const resolved = candidates.find((path16) => existsSync(path16));
|
|
312
|
+
if (!resolved) {
|
|
313
|
+
throw new Error(`Missing SQLite migration SQL: ${filename} (searched ${searchSubdirs.join(", ")})`);
|
|
314
|
+
}
|
|
315
|
+
return readFileSync(resolved, "utf8");
|
|
316
|
+
}
|
|
317
|
+
function readCliSqliteMigrationSql(filename) {
|
|
318
|
+
return readMigrationSql(filename, "migrations");
|
|
319
|
+
}
|
|
320
|
+
function readCodeNavCacheMigrationSql(filename) {
|
|
321
|
+
return readMigrationSql(filename, "code-nav-cache-migrations", "code-nav-cache/migrations");
|
|
322
|
+
}
|
|
323
|
+
var init_read_migration_sql = __esm({
|
|
324
|
+
"src/sqlite/read-migration-sql.ts"() {
|
|
325
|
+
"use strict";
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
// src/sqlite/run-sqlite-migrations.ts
|
|
330
|
+
function checkpointSatisfiedByLegacyChain(applied, replacesLegacyMigrations) {
|
|
331
|
+
return Array.isArray(replacesLegacyMigrations) && replacesLegacyMigrations.length > 0 && replacesLegacyMigrations.every((n) => applied.has(n));
|
|
332
|
+
}
|
|
333
|
+
function recordMigrationAndPruneCheckpointLegacy(db, migration, applied) {
|
|
334
|
+
db.run("INSERT INTO __migrations (name) VALUES (?)", [migration.name]);
|
|
335
|
+
applied.add(migration.name);
|
|
336
|
+
if (migration.checkpoint !== true) return;
|
|
337
|
+
const legacy = migration.replacesLegacyMigrations;
|
|
338
|
+
if (!legacy?.length) return;
|
|
339
|
+
for (const legacyName of legacy) {
|
|
340
|
+
if (legacyName === migration.name) continue;
|
|
341
|
+
db.run("DELETE FROM __migrations WHERE name = ?", [legacyName]);
|
|
342
|
+
applied.delete(legacyName);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function runSqliteMigrations(db, migrations, bootstrapSql, label) {
|
|
346
|
+
db.exec(bootstrapSql);
|
|
347
|
+
const appliedRows = db.all("SELECT name FROM __migrations");
|
|
348
|
+
const applied = new Set(appliedRows.map((r) => r.name));
|
|
349
|
+
for (const migration of migrations) {
|
|
350
|
+
if (applied.has(migration.name)) continue;
|
|
351
|
+
if (migration.checkpoint === true && checkpointSatisfiedByLegacyChain(applied, migration.replacesLegacyMigrations)) {
|
|
352
|
+
recordMigrationAndPruneCheckpointLegacy(db, migration, applied);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (migration.alreadyApplied?.(db)) {
|
|
356
|
+
recordMigrationAndPruneCheckpointLegacy(db, migration, applied);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
migration.migrate(db);
|
|
361
|
+
recordMigrationAndPruneCheckpointLegacy(db, migration, applied);
|
|
362
|
+
} catch (e) {
|
|
363
|
+
console.error(`[${label}] Migration failed: ${migration.name}`, e);
|
|
364
|
+
throw e;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
var init_run_sqlite_migrations = __esm({
|
|
369
|
+
"src/sqlite/run-sqlite-migrations.ts"() {
|
|
370
|
+
"use strict";
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// src/sqlite/code-nav-cache/migrate-code-nav-cache-sqlite.ts
|
|
375
|
+
function migrateCodeNavCacheSqlite(db) {
|
|
376
|
+
runSqliteMigrations(
|
|
377
|
+
db,
|
|
378
|
+
CODE_NAV_CACHE_SQLITE_MIGRATIONS,
|
|
379
|
+
readCodeNavCacheMigrationSql("000_bootstrap_migrations_table.sql"),
|
|
380
|
+
"code-nav-cache"
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
var CHECKPOINT_V1, CHECKPOINT_V1_SQL, MIGRATION_002, MIGRATION_002_SQL, MIGRATION_003, MIGRATION_003_SQL, CODE_NAV_CACHE_SQLITE_MIGRATIONS;
|
|
384
|
+
var init_migrate_code_nav_cache_sqlite = __esm({
|
|
385
|
+
"src/sqlite/code-nav-cache/migrate-code-nav-cache-sqlite.ts"() {
|
|
386
|
+
"use strict";
|
|
387
|
+
init_read_migration_sql();
|
|
388
|
+
init_run_sqlite_migrations();
|
|
389
|
+
CHECKPOINT_V1 = "001_code_nav_cache_checkpoint_v1";
|
|
390
|
+
CHECKPOINT_V1_SQL = readCodeNavCacheMigrationSql("001_code_nav_cache_checkpoint_v1.sql");
|
|
391
|
+
MIGRATION_002 = "002_content_hash_symbol_index";
|
|
392
|
+
MIGRATION_002_SQL = readCodeNavCacheMigrationSql("002_content_hash_symbol_index.sql");
|
|
393
|
+
MIGRATION_003 = "003_content_hash_tag_rows";
|
|
394
|
+
MIGRATION_003_SQL = readCodeNavCacheMigrationSql("003_content_hash_tag_rows.sql");
|
|
395
|
+
CODE_NAV_CACHE_SQLITE_MIGRATIONS = [
|
|
396
|
+
{
|
|
397
|
+
name: CHECKPOINT_V1,
|
|
398
|
+
checkpoint: true,
|
|
399
|
+
migrate: (db) => {
|
|
400
|
+
db.exec(CHECKPOINT_V1_SQL);
|
|
401
|
+
},
|
|
402
|
+
alreadyApplied: (db) => {
|
|
403
|
+
const row = db.get(
|
|
404
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='file_index_parent_path' LIMIT 1`
|
|
405
|
+
);
|
|
406
|
+
return row != null;
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
name: MIGRATION_002,
|
|
411
|
+
migrate: (db) => {
|
|
412
|
+
db.exec(MIGRATION_002_SQL);
|
|
413
|
+
},
|
|
414
|
+
alreadyApplied: (db) => {
|
|
415
|
+
const row = db.get(
|
|
416
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_file_blob' LIMIT 1`
|
|
417
|
+
);
|
|
418
|
+
return row != null;
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: MIGRATION_003,
|
|
423
|
+
migrate: (db) => {
|
|
424
|
+
db.exec(MIGRATION_003_SQL);
|
|
425
|
+
},
|
|
426
|
+
alreadyApplied: (db) => {
|
|
427
|
+
const row = db.get(
|
|
428
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_index_tag' LIMIT 1`
|
|
429
|
+
);
|
|
430
|
+
if (row == null) return false;
|
|
431
|
+
const blob = db.get(
|
|
432
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_file_blob' LIMIT 1`
|
|
433
|
+
);
|
|
434
|
+
return blob == null;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
];
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
// src/sqlite/code-nav-cache/code-nav-cache-sqlite-work-lock.ts
|
|
442
|
+
import fs3 from "node:fs";
|
|
443
|
+
function isSqliteCorruptError(e) {
|
|
444
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
445
|
+
return msg.includes("malformed") || msg.includes("database disk image is malformed") || msg.includes("corrupt");
|
|
446
|
+
}
|
|
447
|
+
function withCodeNavCacheSqliteWorkLock(fn) {
|
|
448
|
+
if (workLockDepth > 0) {
|
|
449
|
+
return Promise.resolve(fn());
|
|
450
|
+
}
|
|
451
|
+
const run = async () => {
|
|
452
|
+
workLockDepth += 1;
|
|
453
|
+
try {
|
|
454
|
+
return await Promise.resolve(fn());
|
|
455
|
+
} finally {
|
|
456
|
+
workLockDepth = Math.max(0, workLockDepth - 1);
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
const runWithCorruptRecovery = async () => {
|
|
460
|
+
try {
|
|
461
|
+
return await run();
|
|
462
|
+
} catch (e) {
|
|
463
|
+
if (!isSqliteCorruptError(e)) throw e;
|
|
464
|
+
try {
|
|
465
|
+
fs3.unlinkSync(getCodeNavCacheSqlitePath());
|
|
466
|
+
} catch {
|
|
467
|
+
}
|
|
468
|
+
chain = Promise.resolve();
|
|
469
|
+
return await run();
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
const next = chain.then(runWithCorruptRecovery);
|
|
473
|
+
chain = next.then(
|
|
474
|
+
() => void 0,
|
|
475
|
+
() => void 0
|
|
476
|
+
);
|
|
477
|
+
return next;
|
|
478
|
+
}
|
|
479
|
+
var chain, workLockDepth;
|
|
480
|
+
var init_code_nav_cache_sqlite_work_lock = __esm({
|
|
481
|
+
"src/sqlite/code-nav-cache/code-nav-cache-sqlite-work-lock.ts"() {
|
|
482
|
+
"use strict";
|
|
483
|
+
init_code_nav_cache_paths();
|
|
484
|
+
chain = Promise.resolve();
|
|
485
|
+
workLockDepth = 0;
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
// src/sqlite/code-nav-cache/code-nav-cache-database.ts
|
|
490
|
+
async function waitForOuterCodeNavCacheAccessAsync() {
|
|
491
|
+
while (codeNavCacheAccessDepth > 0) {
|
|
492
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
493
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
494
|
+
await yieldToEventLoop();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
async function withCodeNavCacheSqlite(fn) {
|
|
498
|
+
return withCodeNavCacheSqliteWorkLock(async () => {
|
|
499
|
+
const nested = codeNavCacheAccessDepth > 0;
|
|
500
|
+
if (!nested) await waitForOuterCodeNavCacheAccessAsync();
|
|
501
|
+
codeNavCacheAccessDepth += 1;
|
|
502
|
+
try {
|
|
503
|
+
return await codeNavCacheSqlite.withAsync(fn);
|
|
504
|
+
} finally {
|
|
505
|
+
codeNavCacheAccessDepth = Math.max(0, codeNavCacheAccessDepth - 1);
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
var codeNavCacheSqlite, codeNavCacheAccessDepth, safeCloseCodeNavCacheSqliteDatabase, openCodeNavCacheSqliteConnection;
|
|
510
|
+
var init_code_nav_cache_database = __esm({
|
|
511
|
+
"src/sqlite/code-nav-cache/code-nav-cache-database.ts"() {
|
|
512
|
+
"use strict";
|
|
513
|
+
init_yield_to_event_loop();
|
|
514
|
+
init_cli_process_interrupt();
|
|
515
|
+
init_create_sqlite_database_access();
|
|
516
|
+
init_sqlite_errors();
|
|
517
|
+
init_code_nav_cache_paths();
|
|
518
|
+
init_migrate_code_nav_cache_sqlite();
|
|
519
|
+
init_code_nav_cache_sqlite_work_lock();
|
|
520
|
+
init_sqlite_errors();
|
|
521
|
+
codeNavCacheSqlite = createSqliteDatabaseAccess({
|
|
522
|
+
getPath: getCodeNavCacheSqlitePath,
|
|
523
|
+
ensureParentDir: ensureCodeNavCacheSqliteParentDir,
|
|
524
|
+
migrate: migrateCodeNavCacheSqlite
|
|
525
|
+
});
|
|
526
|
+
codeNavCacheAccessDepth = 0;
|
|
527
|
+
safeCloseCodeNavCacheSqliteDatabase = codeNavCacheSqlite.safeClose;
|
|
528
|
+
openCodeNavCacheSqliteConnection = codeNavCacheSqlite.openConnection;
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
// src/sqlite/code-nav-cache/code-nav-cache-sqlite-transaction.ts
|
|
533
|
+
function runCodeNavCacheWriteTransaction(db, fn) {
|
|
534
|
+
db.run("BEGIN IMMEDIATE");
|
|
535
|
+
try {
|
|
536
|
+
const result = fn();
|
|
537
|
+
db.run("COMMIT");
|
|
538
|
+
return result;
|
|
539
|
+
} catch (e) {
|
|
540
|
+
try {
|
|
541
|
+
db.run("ROLLBACK");
|
|
542
|
+
} catch {
|
|
543
|
+
}
|
|
544
|
+
throw e;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
var init_code_nav_cache_sqlite_transaction = __esm({
|
|
548
|
+
"src/sqlite/code-nav-cache/code-nav-cache-sqlite-transaction.ts"() {
|
|
549
|
+
"use strict";
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
// src/code-nav/symbol-index/deferred-indexing.ts
|
|
554
|
+
function isSymbolIndexDeferredError(err) {
|
|
555
|
+
return err instanceof SymbolIndexDeferredError;
|
|
556
|
+
}
|
|
557
|
+
var SymbolIndexDeferredError;
|
|
558
|
+
var init_deferred_indexing = __esm({
|
|
559
|
+
"src/code-nav/symbol-index/deferred-indexing.ts"() {
|
|
560
|
+
"use strict";
|
|
561
|
+
SymbolIndexDeferredError = class extends Error {
|
|
562
|
+
constructor() {
|
|
563
|
+
super("Symbol indexing deferred for file browser");
|
|
564
|
+
this.name = "SymbolIndexDeferredError";
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// src/files/browser/file-browser-in-flight.ts
|
|
571
|
+
function registerFileBrowserActivityListener(listener) {
|
|
572
|
+
activityListeners.add(listener);
|
|
573
|
+
return () => {
|
|
574
|
+
activityListeners.delete(listener);
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function fileBrowserRequestInFlight() {
|
|
578
|
+
return inFlightFileBrowserRequests > 0;
|
|
579
|
+
}
|
|
580
|
+
function isBridgeBrowseInteractiveActive() {
|
|
581
|
+
if (fileBrowserRequestInFlight()) return true;
|
|
582
|
+
return Date.now() - lastBrowseActivityAt < BROWSE_INDEX_COOLDOWN_MS;
|
|
583
|
+
}
|
|
584
|
+
function assertBackgroundIndexingAllowed() {
|
|
585
|
+
if (isBridgeBrowseInteractiveActive()) throw new SymbolIndexDeferredError();
|
|
586
|
+
}
|
|
587
|
+
async function yieldUntilFileBrowserIdle(pollMs = 5) {
|
|
588
|
+
while (isBridgeBrowseInteractiveActive()) {
|
|
589
|
+
await yieldToEventLoop();
|
|
590
|
+
if (isBridgeBrowseInteractiveActive()) {
|
|
591
|
+
await new Promise((resolve) => setTimeout(resolve, pollMs));
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
async function yieldForBridgeInteractivePriority() {
|
|
596
|
+
await yieldToEventLoop();
|
|
597
|
+
await yieldUntilFileBrowserIdle();
|
|
598
|
+
}
|
|
599
|
+
var BROWSE_INDEX_COOLDOWN_MS, inFlightFileBrowserRequests, lastBrowseActivityAt, activityListeners;
|
|
600
|
+
var init_file_browser_in_flight = __esm({
|
|
601
|
+
"src/files/browser/file-browser-in-flight.ts"() {
|
|
602
|
+
"use strict";
|
|
603
|
+
init_yield_to_event_loop();
|
|
604
|
+
init_deferred_indexing();
|
|
605
|
+
BROWSE_INDEX_COOLDOWN_MS = 2500;
|
|
606
|
+
inFlightFileBrowserRequests = 0;
|
|
607
|
+
lastBrowseActivityAt = 0;
|
|
608
|
+
activityListeners = /* @__PURE__ */ new Set();
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
// src/code-nav/yield-during-work.ts
|
|
613
|
+
function createCodeNavYieldState() {
|
|
614
|
+
return { n: 0 };
|
|
615
|
+
}
|
|
616
|
+
async function yieldDuringCodeNavWork(state) {
|
|
617
|
+
state.n++;
|
|
618
|
+
if (state.n % CODE_NAV_YIELD_EVERY !== 0) return;
|
|
619
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
620
|
+
await yieldForBridgeInteractivePriority();
|
|
621
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
622
|
+
}
|
|
623
|
+
var CODE_NAV_YIELD_EVERY;
|
|
624
|
+
var init_yield_during_work = __esm({
|
|
625
|
+
"src/code-nav/yield-during-work.ts"() {
|
|
626
|
+
"use strict";
|
|
627
|
+
init_cli_process_interrupt();
|
|
628
|
+
init_file_browser_in_flight();
|
|
629
|
+
init_code_nav_cache_database();
|
|
630
|
+
CODE_NAV_YIELD_EVERY = 64;
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
// src/sqlite/cli-sqlite-paths.ts
|
|
635
|
+
import fs4 from "node:fs";
|
|
636
|
+
import path3 from "node:path";
|
|
637
|
+
import os2 from "node:os";
|
|
638
|
+
function getCliSqlitePath() {
|
|
639
|
+
const override = process.env.BUILDAMATON_CLI_SQLITE_PATH?.trim();
|
|
640
|
+
if (override) return path3.resolve(override);
|
|
641
|
+
return path3.join(os2.homedir(), ".buildautomaton", "cli.sqlite");
|
|
642
|
+
}
|
|
643
|
+
function ensureCliSqliteParentDir(sqlitePath) {
|
|
644
|
+
const dir = path3.dirname(sqlitePath);
|
|
645
|
+
if (!fs4.existsSync(dir)) fs4.mkdirSync(dir, { recursive: true });
|
|
646
|
+
}
|
|
647
|
+
var init_cli_sqlite_paths = __esm({
|
|
648
|
+
"src/sqlite/cli-sqlite-paths.ts"() {
|
|
649
|
+
"use strict";
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
// src/files/index/constants.ts
|
|
654
|
+
import path4 from "node:path";
|
|
655
|
+
import os3 from "node:os";
|
|
656
|
+
var INDEX_WORK_YIELD_EVERY, INDEX_DIR, INDEX_HASH_LEN;
|
|
657
|
+
var init_constants = __esm({
|
|
658
|
+
"src/files/index/constants.ts"() {
|
|
659
|
+
"use strict";
|
|
660
|
+
INDEX_WORK_YIELD_EVERY = 128;
|
|
661
|
+
INDEX_DIR = path4.join(os3.homedir(), ".buildautomaton");
|
|
662
|
+
INDEX_HASH_LEN = 16;
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
// src/prompt-turn-queue/paths.ts
|
|
667
|
+
import path5 from "node:path";
|
|
668
|
+
import os4 from "node:os";
|
|
669
|
+
function getPromptQueuesDirectory() {
|
|
670
|
+
const override = process.env.BUILDAMATON_PROMPT_QUEUES_DIR?.trim();
|
|
671
|
+
if (override) return path5.resolve(override);
|
|
672
|
+
return path5.join(os4.homedir(), ".buildautomaton", "queues");
|
|
673
|
+
}
|
|
674
|
+
var init_paths = __esm({
|
|
675
|
+
"src/prompt-turn-queue/paths.ts"() {
|
|
676
|
+
"use strict";
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
// src/sqlite/legacy_migration/archive-to-old-version.ts
|
|
681
|
+
import fs5 from "node:fs";
|
|
682
|
+
import path6 from "node:path";
|
|
683
|
+
function moveLegacyFileToOldVersionBackup(category, sourcePath) {
|
|
684
|
+
const destDir = path6.join(OLD_VERSION_DIR, category);
|
|
685
|
+
fs5.mkdirSync(destDir, { recursive: true });
|
|
686
|
+
const base = path6.basename(sourcePath);
|
|
687
|
+
let dest = path6.join(destDir, base);
|
|
688
|
+
if (fs5.existsSync(dest)) {
|
|
689
|
+
const ext = path6.extname(base);
|
|
690
|
+
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
691
|
+
dest = path6.join(destDir, `${stem}-${Date.now()}${ext}`);
|
|
692
|
+
}
|
|
693
|
+
fs5.renameSync(sourcePath, dest);
|
|
694
|
+
}
|
|
695
|
+
var OLD_VERSION_DIR;
|
|
696
|
+
var init_archive_to_old_version = __esm({
|
|
697
|
+
"src/sqlite/legacy_migration/archive-to-old-version.ts"() {
|
|
698
|
+
"use strict";
|
|
699
|
+
init_constants();
|
|
700
|
+
OLD_VERSION_DIR = path6.join(INDEX_DIR, "old-version");
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
// src/sqlite/legacy_migration/archive-file-index-json.ts
|
|
705
|
+
import fs6 from "node:fs";
|
|
706
|
+
import path7 from "node:path";
|
|
707
|
+
function archiveLegacyFileIndexJsonFiles() {
|
|
708
|
+
try {
|
|
709
|
+
if (!fs6.existsSync(INDEX_DIR)) return;
|
|
710
|
+
for (const name of fs6.readdirSync(INDEX_DIR)) {
|
|
711
|
+
if (name.startsWith(".file-index-") && name.endsWith(".json")) {
|
|
712
|
+
const full = path7.join(INDEX_DIR, name);
|
|
713
|
+
try {
|
|
714
|
+
moveLegacyFileToOldVersionBackup("file-index", full);
|
|
715
|
+
} catch (err) {
|
|
716
|
+
console.error(`[cli-sqlite] legacy import: could not archive ${name}`, err);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
} catch (e) {
|
|
721
|
+
console.error("[cli-sqlite] legacy import: archive file-index json failed", e);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
var init_archive_file_index_json = __esm({
|
|
725
|
+
"src/sqlite/legacy_migration/archive-file-index-json.ts"() {
|
|
726
|
+
"use strict";
|
|
727
|
+
init_constants();
|
|
728
|
+
init_archive_to_old_version();
|
|
729
|
+
}
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
// src/sqlite/legacy_migration/import-agent-sessions-from-disk.ts
|
|
733
|
+
import fs7 from "node:fs";
|
|
734
|
+
import path8 from "node:path";
|
|
735
|
+
import os5 from "node:os";
|
|
736
|
+
function importLegacyAgentSessionsFromDisk(db) {
|
|
737
|
+
try {
|
|
738
|
+
if (!fs7.existsSync(LEGACY_AGENT_SESSION_DIR)) return;
|
|
739
|
+
const names = fs7.readdirSync(LEGACY_AGENT_SESSION_DIR).filter((n) => n.endsWith(".json"));
|
|
740
|
+
for (const name of names) {
|
|
741
|
+
const sessionKey = name.slice(0, -".json".length);
|
|
742
|
+
const full = path8.join(LEGACY_AGENT_SESSION_DIR, name);
|
|
743
|
+
let raw;
|
|
744
|
+
try {
|
|
745
|
+
raw = fs7.readFileSync(full, "utf8");
|
|
746
|
+
} catch {
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
let parsed;
|
|
750
|
+
try {
|
|
751
|
+
parsed = JSON.parse(raw);
|
|
752
|
+
} catch {
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
if (parsed.v !== 1) continue;
|
|
756
|
+
const acpSessionId = typeof parsed.acpSessionId === "string" ? parsed.acpSessionId : null;
|
|
757
|
+
const backendAgentType = typeof parsed.backendAgentType === "string" ? parsed.backendAgentType : null;
|
|
758
|
+
const configOptionsJson = Array.isArray(parsed.configOptions) ? JSON.stringify(parsed.configOptions) : null;
|
|
759
|
+
const updatedAt = typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
760
|
+
db.run(
|
|
761
|
+
`INSERT OR REPLACE INTO agent_session (session_key, acp_session_id, backend_agent_type, config_options_json, updated_at)
|
|
762
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
763
|
+
[sessionKey, acpSessionId, backendAgentType, configOptionsJson, updatedAt]
|
|
764
|
+
);
|
|
765
|
+
try {
|
|
766
|
+
moveLegacyFileToOldVersionBackup("agent-sessions", full);
|
|
767
|
+
} catch {
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
} catch (e) {
|
|
771
|
+
console.error("[cli-sqlite] legacy import: agent_sessions from disk failed", e);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
var LEGACY_AGENT_SESSION_DIR;
|
|
775
|
+
var init_import_agent_sessions_from_disk = __esm({
|
|
776
|
+
"src/sqlite/legacy_migration/import-agent-sessions-from-disk.ts"() {
|
|
777
|
+
"use strict";
|
|
778
|
+
init_archive_to_old_version();
|
|
779
|
+
LEGACY_AGENT_SESSION_DIR = path8.join(os5.homedir(), ".buildautomaton", "agent-sessions");
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
|
|
783
|
+
// src/sqlite/legacy_migration/parse-persisted-queue-json.ts
|
|
784
|
+
function parsePersistedQueueFromJson(raw) {
|
|
785
|
+
try {
|
|
786
|
+
const o = JSON.parse(raw);
|
|
787
|
+
const queueKey = typeof o.queueKey === "string" ? o.queueKey : typeof o.queueKeyHash === "string" ? o.queueKeyHash : null;
|
|
788
|
+
if (!queueKey || typeof o.updatedAt !== "string" || !Array.isArray(o.turns)) return null;
|
|
789
|
+
return { queueKey, updatedAt: o.updatedAt, turns: o.turns };
|
|
790
|
+
} catch {
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
var init_parse_persisted_queue_json = __esm({
|
|
795
|
+
"src/sqlite/legacy_migration/parse-persisted-queue-json.ts"() {
|
|
796
|
+
"use strict";
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
// src/sqlite/legacy_migration/import-prompt-queues-from-disk.ts
|
|
801
|
+
import fs8 from "node:fs";
|
|
802
|
+
import path9 from "node:path";
|
|
803
|
+
function importLegacyPromptQueuesFromDisk(db) {
|
|
804
|
+
try {
|
|
805
|
+
const dir = getPromptQueuesDirectory();
|
|
806
|
+
if (!fs8.existsSync(dir)) return;
|
|
807
|
+
for (const name of fs8.readdirSync(dir)) {
|
|
808
|
+
if (!name.endsWith(".json")) continue;
|
|
809
|
+
const full = path9.join(dir, name);
|
|
810
|
+
let raw;
|
|
811
|
+
try {
|
|
812
|
+
raw = fs8.readFileSync(full, "utf8");
|
|
813
|
+
} catch {
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
816
|
+
const file = parsePersistedQueueFromJson(raw);
|
|
817
|
+
if (!file) continue;
|
|
818
|
+
db.run(
|
|
819
|
+
`INSERT OR REPLACE INTO prompt_queue (queue_key, updated_at, turns_json) VALUES (?, ?, ?)`,
|
|
820
|
+
[file.queueKey, file.updatedAt, JSON.stringify(file.turns)]
|
|
821
|
+
);
|
|
822
|
+
try {
|
|
823
|
+
moveLegacyFileToOldVersionBackup("queues", full);
|
|
824
|
+
} catch {
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
} catch (e) {
|
|
828
|
+
console.error("[cli-sqlite] legacy import: prompt queues from disk failed", e);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
var init_import_prompt_queues_from_disk = __esm({
|
|
832
|
+
"src/sqlite/legacy_migration/import-prompt-queues-from-disk.ts"() {
|
|
833
|
+
"use strict";
|
|
834
|
+
init_paths();
|
|
835
|
+
init_archive_to_old_version();
|
|
836
|
+
init_parse_persisted_queue_json();
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
// src/sqlite/legacy_migration/import-cli-legacy-disk-data.ts
|
|
841
|
+
import fs9 from "node:fs";
|
|
842
|
+
function legacyCliDiskMigrationIsPending() {
|
|
843
|
+
try {
|
|
844
|
+
if (fs9.existsSync(INDEX_DIR)) {
|
|
845
|
+
for (const name of fs9.readdirSync(INDEX_DIR)) {
|
|
846
|
+
if (name.startsWith(".file-index-") && name.endsWith(".json")) return true;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
} catch {
|
|
850
|
+
}
|
|
851
|
+
try {
|
|
852
|
+
if (fs9.existsSync(LEGACY_AGENT_SESSION_DIR)) {
|
|
853
|
+
if (fs9.readdirSync(LEGACY_AGENT_SESSION_DIR).some((n) => n.endsWith(".json"))) return true;
|
|
854
|
+
}
|
|
855
|
+
} catch {
|
|
856
|
+
}
|
|
857
|
+
try {
|
|
858
|
+
const dir = getPromptQueuesDirectory();
|
|
859
|
+
if (fs9.existsSync(dir) && fs9.readdirSync(dir).some((n) => n.endsWith(".json"))) return true;
|
|
860
|
+
} catch {
|
|
861
|
+
}
|
|
862
|
+
return false;
|
|
863
|
+
}
|
|
864
|
+
function importCliSqliteLegacyDiskData(db, log) {
|
|
865
|
+
const pending = legacyCliDiskMigrationIsPending();
|
|
866
|
+
if (pending && log) {
|
|
867
|
+
log("Migrating legacy on-disk CLI data to SQLite\u2026");
|
|
868
|
+
}
|
|
869
|
+
archiveLegacyFileIndexJsonFiles();
|
|
870
|
+
importLegacyAgentSessionsFromDisk(db);
|
|
871
|
+
importLegacyPromptQueuesFromDisk(db);
|
|
872
|
+
if (pending && log) {
|
|
873
|
+
log("Legacy on-disk CLI data migration finished.");
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
var init_import_cli_legacy_disk_data = __esm({
|
|
877
|
+
"src/sqlite/legacy_migration/import-cli-legacy-disk-data.ts"() {
|
|
878
|
+
"use strict";
|
|
879
|
+
init_constants();
|
|
880
|
+
init_paths();
|
|
881
|
+
init_archive_file_index_json();
|
|
882
|
+
init_import_agent_sessions_from_disk();
|
|
883
|
+
init_import_prompt_queues_from_disk();
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
|
|
887
|
+
// src/sqlite/migrate-cli-sqlite.ts
|
|
888
|
+
function agentCapabilitiesTableState(db) {
|
|
889
|
+
const rows = db.all(
|
|
890
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name IN ('agent_capabilities', 'agent_capability_cache')`
|
|
891
|
+
);
|
|
892
|
+
const names = new Set(rows.map((r) => r.name));
|
|
893
|
+
if (names.has("agent_capabilities")) return "current";
|
|
894
|
+
if (names.has("agent_capability_cache")) return "legacy";
|
|
895
|
+
return "new";
|
|
896
|
+
}
|
|
897
|
+
function migrateCliSqlite(db) {
|
|
898
|
+
runSqliteMigrations(
|
|
899
|
+
db,
|
|
900
|
+
CLI_SQLITE_MIGRATIONS,
|
|
901
|
+
readCliSqliteMigrationSql("000_bootstrap_migrations_table.sql"),
|
|
902
|
+
"cli-sqlite"
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
var CHECKPOINT_V12, CHECKPOINT_V1_SQL2, AGENT_CAPABILITIES_SQL, DROP_CACHE_TABLES_SQL, CLI_SQLITE_MIGRATIONS;
|
|
906
|
+
var init_migrate_cli_sqlite = __esm({
|
|
907
|
+
"src/sqlite/migrate-cli-sqlite.ts"() {
|
|
908
|
+
"use strict";
|
|
909
|
+
init_read_migration_sql();
|
|
910
|
+
init_run_sqlite_migrations();
|
|
911
|
+
CHECKPOINT_V12 = "001_cli_sqlite_checkpoint_v1";
|
|
912
|
+
CHECKPOINT_V1_SQL2 = readCliSqliteMigrationSql("001_cli_sqlite_checkpoint_v1.sql");
|
|
913
|
+
AGENT_CAPABILITIES_SQL = readCliSqliteMigrationSql("002_agent_capabilities.sql");
|
|
914
|
+
DROP_CACHE_TABLES_SQL = readCliSqliteMigrationSql("006_drop_cache_tables.sql");
|
|
915
|
+
CLI_SQLITE_MIGRATIONS = [
|
|
916
|
+
{
|
|
917
|
+
name: CHECKPOINT_V12,
|
|
918
|
+
checkpoint: true,
|
|
919
|
+
migrate: (db) => {
|
|
920
|
+
db.exec(CHECKPOINT_V1_SQL2);
|
|
921
|
+
}
|
|
922
|
+
},
|
|
923
|
+
{
|
|
924
|
+
name: "002_agent_capabilities",
|
|
925
|
+
migrate: (db) => {
|
|
926
|
+
const state = agentCapabilitiesTableState(db);
|
|
927
|
+
if (state === "current") return;
|
|
928
|
+
if (state === "legacy") {
|
|
929
|
+
db.exec(`
|
|
930
|
+
ALTER TABLE agent_capability_cache RENAME TO agent_capabilities;
|
|
931
|
+
DROP INDEX IF EXISTS idx_agent_capability_cache_workspace;
|
|
932
|
+
CREATE INDEX IF NOT EXISTS idx_agent_capabilities_workspace ON agent_capabilities(workspace_id);
|
|
933
|
+
`);
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
db.exec(AGENT_CAPABILITIES_SQL);
|
|
937
|
+
},
|
|
938
|
+
alreadyApplied: (db) => agentCapabilitiesTableState(db) === "current"
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
name: "006_drop_cache_tables",
|
|
942
|
+
migrate: (db) => {
|
|
943
|
+
db.exec(DROP_CACHE_TABLES_SQL);
|
|
944
|
+
},
|
|
945
|
+
alreadyApplied: (db) => {
|
|
946
|
+
const row = db.get(
|
|
947
|
+
`SELECT 1 as ok FROM sqlite_master
|
|
948
|
+
WHERE type='table' AND name IN ('file_index_parent_path', 'file_index_child_path', 'file_index_path')
|
|
949
|
+
LIMIT 1`
|
|
950
|
+
);
|
|
951
|
+
return row == null;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
];
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
// src/sqlite/cli-database.ts
|
|
959
|
+
var cliSqlite, safeCloseCliSqliteDatabase, closeAllCliSqliteConnections, openCliSqliteConnection, withCliSqliteSync, withCliSqlite, ensureCliSqliteInitialized;
|
|
960
|
+
var init_cli_database = __esm({
|
|
961
|
+
"src/sqlite/cli-database.ts"() {
|
|
962
|
+
"use strict";
|
|
963
|
+
init_cli_process_interrupt();
|
|
964
|
+
init_cli_sqlite_paths();
|
|
965
|
+
init_create_sqlite_database_access();
|
|
966
|
+
init_import_cli_legacy_disk_data();
|
|
967
|
+
init_migrate_cli_sqlite();
|
|
968
|
+
init_sqlite_errors();
|
|
969
|
+
cliSqlite = createSqliteDatabaseAccess({
|
|
970
|
+
getPath: getCliSqlitePath,
|
|
971
|
+
ensureParentDir: ensureCliSqliteParentDir,
|
|
972
|
+
migrate: migrateCliSqlite,
|
|
973
|
+
afterOpen: (db, options) => {
|
|
974
|
+
importCliSqliteLegacyDiskData(db, options?.logLegacyMigration);
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
safeCloseCliSqliteDatabase = cliSqlite.safeClose;
|
|
978
|
+
closeAllCliSqliteConnections = cliSqlite.closeAllConnections;
|
|
979
|
+
openCliSqliteConnection = cliSqlite.openConnection;
|
|
980
|
+
withCliSqliteSync = cliSqlite.withSync;
|
|
981
|
+
withCliSqlite = cliSqlite.withAsync;
|
|
982
|
+
ensureCliSqliteInitialized = cliSqlite.ensureInitialized;
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
// src/files/index/walk-workspace-tree.ts
|
|
987
|
+
function shouldSkipWorkspaceWalkEntry(name) {
|
|
988
|
+
return DEPENDENCY_INSTALL_DIR_NAMES.has(name);
|
|
989
|
+
}
|
|
990
|
+
function createWalkYieldState() {
|
|
991
|
+
return { n: 0 };
|
|
992
|
+
}
|
|
993
|
+
var DEPENDENCY_INSTALL_DIR_NAMES;
|
|
994
|
+
var init_walk_workspace_tree = __esm({
|
|
995
|
+
"src/files/index/walk-workspace-tree.ts"() {
|
|
996
|
+
"use strict";
|
|
997
|
+
init_file_browser_in_flight();
|
|
998
|
+
init_cli_process_interrupt();
|
|
999
|
+
init_cli_database();
|
|
1000
|
+
init_constants();
|
|
1001
|
+
DEPENDENCY_INSTALL_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
1002
|
+
"node_modules",
|
|
1003
|
+
"bower_components",
|
|
1004
|
+
"vendor",
|
|
1005
|
+
"Pods",
|
|
1006
|
+
"Carthage",
|
|
1007
|
+
"DerivedData",
|
|
1008
|
+
".yarn",
|
|
1009
|
+
".pnpm-store"
|
|
1010
|
+
]);
|
|
1011
|
+
}
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
// ../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
|
|
1015
|
+
var require_ignore = __commonJS({
|
|
1016
|
+
"../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js"(exports, module) {
|
|
1017
|
+
function makeArray(subject) {
|
|
1018
|
+
return Array.isArray(subject) ? subject : [subject];
|
|
1019
|
+
}
|
|
1020
|
+
var UNDEFINED = void 0;
|
|
1021
|
+
var EMPTY = "";
|
|
1022
|
+
var SPACE = " ";
|
|
1023
|
+
var ESCAPE = "\\";
|
|
1024
|
+
var REGEX_TEST_BLANK_LINE = /^\s+$/;
|
|
1025
|
+
var REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\]|^)\\$/;
|
|
1026
|
+
var REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/;
|
|
1027
|
+
var REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/;
|
|
1028
|
+
var REGEX_SPLITALL_CRLF = /\r?\n/g;
|
|
1029
|
+
var REGEX_TEST_INVALID_PATH = /^\.{0,2}\/|^\.{1,2}$/;
|
|
1030
|
+
var REGEX_TEST_TRAILING_SLASH = /\/$/;
|
|
1031
|
+
var SLASH = "/";
|
|
1032
|
+
var TMP_KEY_IGNORE = "node-ignore";
|
|
1033
|
+
if (typeof Symbol !== "undefined") {
|
|
1034
|
+
TMP_KEY_IGNORE = Symbol.for("node-ignore");
|
|
1035
|
+
}
|
|
1036
|
+
var KEY_IGNORE = TMP_KEY_IGNORE;
|
|
1037
|
+
var define = (object, key, value) => {
|
|
1038
|
+
Object.defineProperty(object, key, { value });
|
|
1039
|
+
return value;
|
|
1040
|
+
};
|
|
1041
|
+
var REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g;
|
|
1042
|
+
var RETURN_FALSE = () => false;
|
|
1043
|
+
var sanitizeRange = (range) => range.replace(
|
|
1044
|
+
REGEX_REGEXP_RANGE,
|
|
1045
|
+
(match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) ? match : EMPTY
|
|
1046
|
+
);
|
|
1047
|
+
var cleanRangeBackSlash = (slashes) => {
|
|
1048
|
+
const { length } = slashes;
|
|
1049
|
+
return slashes.slice(0, length - length % 2);
|
|
1050
|
+
};
|
|
1051
|
+
var REPLACERS = [
|
|
1052
|
+
[
|
|
1053
|
+
// Remove BOM
|
|
1054
|
+
// TODO:
|
|
1055
|
+
// Other similar zero-width characters?
|
|
1056
|
+
/^\uFEFF/,
|
|
1057
|
+
() => EMPTY
|
|
1058
|
+
],
|
|
1059
|
+
// > Trailing spaces are ignored unless they are quoted with backslash ("\")
|
|
1060
|
+
[
|
|
1061
|
+
// (a\ ) -> (a )
|
|
1062
|
+
// (a ) -> (a)
|
|
1063
|
+
// (a ) -> (a)
|
|
1064
|
+
// (a \ ) -> (a )
|
|
1065
|
+
/((?:\\\\)*?)(\\?\s+)$/,
|
|
1066
|
+
(_, m1, m2) => m1 + (m2.indexOf("\\") === 0 ? SPACE : EMPTY)
|
|
1067
|
+
],
|
|
1068
|
+
// Replace (\ ) with ' '
|
|
1069
|
+
// (\ ) -> ' '
|
|
1070
|
+
// (\\ ) -> '\\ '
|
|
1071
|
+
// (\\\ ) -> '\\ '
|
|
1072
|
+
[
|
|
1073
|
+
/(\\+?)\s/g,
|
|
1074
|
+
(_, m1) => {
|
|
1075
|
+
const { length } = m1;
|
|
1076
|
+
return m1.slice(0, length - length % 2) + SPACE;
|
|
1077
|
+
}
|
|
1078
|
+
],
|
|
1079
|
+
// Escape metacharacters
|
|
1080
|
+
// which is written down by users but means special for regular expressions.
|
|
1081
|
+
// > There are 12 characters with special meanings:
|
|
1082
|
+
// > - the backslash \,
|
|
1083
|
+
// > - the caret ^,
|
|
1084
|
+
// > - the dollar sign $,
|
|
1085
|
+
// > - the period or dot .,
|
|
1086
|
+
// > - the vertical bar or pipe symbol |,
|
|
1087
|
+
// > - the question mark ?,
|
|
1088
|
+
// > - the asterisk or star *,
|
|
1089
|
+
// > - the plus sign +,
|
|
1090
|
+
// > - the opening parenthesis (,
|
|
1091
|
+
// > - the closing parenthesis ),
|
|
1092
|
+
// > - and the opening square bracket [,
|
|
1093
|
+
// > - the opening curly brace {,
|
|
1094
|
+
// > These special characters are often called "metacharacters".
|
|
1095
|
+
[
|
|
1096
|
+
/[\\$.|*+(){^]/g,
|
|
1097
|
+
(match) => `\\${match}`
|
|
1098
|
+
],
|
|
1099
|
+
[
|
|
1100
|
+
// > a question mark (?) matches a single character
|
|
1101
|
+
/(?!\\)\?/g,
|
|
1102
|
+
() => "[^/]"
|
|
1103
|
+
],
|
|
1104
|
+
// leading slash
|
|
1105
|
+
[
|
|
1106
|
+
// > A leading slash matches the beginning of the pathname.
|
|
1107
|
+
// > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c".
|
|
1108
|
+
// A leading slash matches the beginning of the pathname
|
|
1109
|
+
/^\//,
|
|
1110
|
+
() => "^"
|
|
1111
|
+
],
|
|
1112
|
+
// replace special metacharacter slash after the leading slash
|
|
1113
|
+
[
|
|
1114
|
+
/\//g,
|
|
1115
|
+
() => "\\/"
|
|
1116
|
+
],
|
|
1117
|
+
[
|
|
1118
|
+
// > A leading "**" followed by a slash means match in all directories.
|
|
1119
|
+
// > For example, "**/foo" matches file or directory "foo" anywhere,
|
|
1120
|
+
// > the same as pattern "foo".
|
|
1121
|
+
// > "**/foo/bar" matches file or directory "bar" anywhere that is directly
|
|
1122
|
+
// > under directory "foo".
|
|
1123
|
+
// Notice that the '*'s have been replaced as '\\*'
|
|
1124
|
+
/^\^*\\\*\\\*\\\//,
|
|
1125
|
+
// '**/foo' <-> 'foo'
|
|
1126
|
+
() => "^(?:.*\\/)?"
|
|
1127
|
+
],
|
|
1128
|
+
// starting
|
|
1129
|
+
[
|
|
1130
|
+
// there will be no leading '/'
|
|
1131
|
+
// (which has been replaced by section "leading slash")
|
|
1132
|
+
// If starts with '**', adding a '^' to the regular expression also works
|
|
1133
|
+
/^(?=[^^])/,
|
|
1134
|
+
function startingReplacer() {
|
|
1135
|
+
return !/\/(?!$)/.test(this) ? "(?:^|\\/)" : "^";
|
|
1136
|
+
}
|
|
1137
|
+
],
|
|
1138
|
+
// two globstars
|
|
1139
|
+
[
|
|
1140
|
+
// Use lookahead assertions so that we could match more than one `'/**'`
|
|
1141
|
+
/\\\/\\\*\\\*(?=\\\/|$)/g,
|
|
1142
|
+
// Zero, one or several directories
|
|
1143
|
+
// should not use '*', or it will be replaced by the next replacer
|
|
1144
|
+
// Check if it is not the last `'/**'`
|
|
1145
|
+
(_, index, str) => index + 6 < str.length ? "(?:\\/[^\\/]+)*" : "\\/.+"
|
|
1146
|
+
],
|
|
1147
|
+
// normal intermediate wildcards
|
|
1148
|
+
[
|
|
1149
|
+
// Never replace escaped '*'
|
|
1150
|
+
// ignore rule '\*' will match the path '*'
|
|
1151
|
+
// 'abc.*/' -> go
|
|
1152
|
+
// 'abc.*' -> skip this rule,
|
|
1153
|
+
// coz trailing single wildcard will be handed by [trailing wildcard]
|
|
1154
|
+
/(^|[^\\]+)(\\\*)+(?=.+)/g,
|
|
1155
|
+
// '*.js' matches '.js'
|
|
1156
|
+
// '*.js' doesn't match 'abc'
|
|
1157
|
+
(_, p1, p2) => {
|
|
1158
|
+
const unescaped = p2.replace(/\\\*/g, "[^\\/]*");
|
|
1159
|
+
return p1 + unescaped;
|
|
1160
|
+
}
|
|
1161
|
+
],
|
|
1162
|
+
[
|
|
1163
|
+
// unescape, revert step 3 except for back slash
|
|
1164
|
+
// For example, if a user escape a '\\*',
|
|
1165
|
+
// after step 3, the result will be '\\\\\\*'
|
|
1166
|
+
/\\\\\\(?=[$.|*+(){^])/g,
|
|
1167
|
+
() => ESCAPE
|
|
1168
|
+
],
|
|
1169
|
+
[
|
|
1170
|
+
// '\\\\' -> '\\'
|
|
1171
|
+
/\\\\/g,
|
|
1172
|
+
() => ESCAPE
|
|
1173
|
+
],
|
|
1174
|
+
[
|
|
1175
|
+
// > The range notation, e.g. [a-zA-Z],
|
|
1176
|
+
// > can be used to match one of the characters in a range.
|
|
1177
|
+
// `\` is escaped by step 3
|
|
1178
|
+
/(\\)?\[([^\]/]*?)(\\*)($|\])/g,
|
|
1179
|
+
(match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` : close === "]" ? endEscape.length % 2 === 0 ? `[${sanitizeRange(range)}${endEscape}]` : "[]" : "[]"
|
|
1180
|
+
],
|
|
1181
|
+
// ending
|
|
1182
|
+
[
|
|
1183
|
+
// 'js' will not match 'js.'
|
|
1184
|
+
// 'ab' will not match 'abc'
|
|
1185
|
+
/(?:[^*])$/,
|
|
1186
|
+
// WTF!
|
|
1187
|
+
// https://git-scm.com/docs/gitignore
|
|
1188
|
+
// changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)
|
|
1189
|
+
// which re-fixes #24, #38
|
|
1190
|
+
// > If there is a separator at the end of the pattern then the pattern
|
|
1191
|
+
// > will only match directories, otherwise the pattern can match both
|
|
1192
|
+
// > files and directories.
|
|
1193
|
+
// 'js*' will not match 'a.js'
|
|
1194
|
+
// 'js/' will not match 'a.js'
|
|
1195
|
+
// 'js' will match 'a.js' and 'a.js/'
|
|
1196
|
+
(match) => /\/$/.test(match) ? `${match}$` : `${match}(?=$|\\/$)`
|
|
1197
|
+
]
|
|
1198
|
+
];
|
|
1199
|
+
var REGEX_REPLACE_TRAILING_WILDCARD = /(^|\\\/)?\\\*$/;
|
|
1200
|
+
var MODE_IGNORE = "regex";
|
|
1201
|
+
var MODE_CHECK_IGNORE = "checkRegex";
|
|
1202
|
+
var UNDERSCORE = "_";
|
|
1203
|
+
var TRAILING_WILD_CARD_REPLACERS = {
|
|
1204
|
+
[MODE_IGNORE](_, p1) {
|
|
1205
|
+
const prefix = p1 ? `${p1}[^/]+` : "[^/]*";
|
|
1206
|
+
return `${prefix}(?=$|\\/$)`;
|
|
1207
|
+
},
|
|
1208
|
+
[MODE_CHECK_IGNORE](_, p1) {
|
|
1209
|
+
const prefix = p1 ? `${p1}[^/]*` : "[^/]*";
|
|
1210
|
+
return `${prefix}(?=$|\\/$)`;
|
|
1211
|
+
}
|
|
1212
|
+
};
|
|
1213
|
+
var makeRegexPrefix = (pattern) => REPLACERS.reduce(
|
|
1214
|
+
(prev, [matcher, replacer]) => prev.replace(matcher, replacer.bind(pattern)),
|
|
1215
|
+
pattern
|
|
1216
|
+
);
|
|
1217
|
+
var isString = (subject) => typeof subject === "string";
|
|
1218
|
+
var checkPattern = (pattern) => pattern && isString(pattern) && !REGEX_TEST_BLANK_LINE.test(pattern) && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern) && pattern.indexOf("#") !== 0;
|
|
1219
|
+
var splitPattern = (pattern) => pattern.split(REGEX_SPLITALL_CRLF).filter(Boolean);
|
|
1220
|
+
var IgnoreRule = class {
|
|
1221
|
+
constructor(pattern, mark, body, ignoreCase, negative, prefix) {
|
|
1222
|
+
this.pattern = pattern;
|
|
1223
|
+
this.mark = mark;
|
|
1224
|
+
this.negative = negative;
|
|
1225
|
+
define(this, "body", body);
|
|
1226
|
+
define(this, "ignoreCase", ignoreCase);
|
|
1227
|
+
define(this, "regexPrefix", prefix);
|
|
1228
|
+
}
|
|
1229
|
+
get regex() {
|
|
1230
|
+
const key = UNDERSCORE + MODE_IGNORE;
|
|
1231
|
+
if (this[key]) {
|
|
1232
|
+
return this[key];
|
|
1233
|
+
}
|
|
1234
|
+
return this._make(MODE_IGNORE, key);
|
|
1235
|
+
}
|
|
1236
|
+
get checkRegex() {
|
|
1237
|
+
const key = UNDERSCORE + MODE_CHECK_IGNORE;
|
|
1238
|
+
if (this[key]) {
|
|
1239
|
+
return this[key];
|
|
1240
|
+
}
|
|
1241
|
+
return this._make(MODE_CHECK_IGNORE, key);
|
|
1242
|
+
}
|
|
1243
|
+
_make(mode, key) {
|
|
1244
|
+
const str = this.regexPrefix.replace(
|
|
1245
|
+
REGEX_REPLACE_TRAILING_WILDCARD,
|
|
1246
|
+
// It does not need to bind pattern
|
|
1247
|
+
TRAILING_WILD_CARD_REPLACERS[mode]
|
|
1248
|
+
);
|
|
1249
|
+
const regex = this.ignoreCase ? new RegExp(str, "i") : new RegExp(str);
|
|
1250
|
+
return define(this, key, regex);
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
var createRule = ({
|
|
1254
|
+
pattern,
|
|
1255
|
+
mark
|
|
1256
|
+
}, ignoreCase) => {
|
|
1257
|
+
let negative = false;
|
|
1258
|
+
let body = pattern;
|
|
1259
|
+
if (body.indexOf("!") === 0) {
|
|
1260
|
+
negative = true;
|
|
1261
|
+
body = body.substr(1);
|
|
1262
|
+
}
|
|
1263
|
+
body = body.replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, "!").replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, "#");
|
|
1264
|
+
const regexPrefix = makeRegexPrefix(body);
|
|
1265
|
+
return new IgnoreRule(
|
|
1266
|
+
pattern,
|
|
1267
|
+
mark,
|
|
1268
|
+
body,
|
|
1269
|
+
ignoreCase,
|
|
1270
|
+
negative,
|
|
1271
|
+
regexPrefix
|
|
1272
|
+
);
|
|
1273
|
+
};
|
|
1274
|
+
var RuleManager = class {
|
|
1275
|
+
constructor(ignoreCase) {
|
|
1276
|
+
this._ignoreCase = ignoreCase;
|
|
1277
|
+
this._rules = [];
|
|
1278
|
+
}
|
|
1279
|
+
_add(pattern) {
|
|
1280
|
+
if (pattern && pattern[KEY_IGNORE]) {
|
|
1281
|
+
this._rules = this._rules.concat(pattern._rules._rules);
|
|
1282
|
+
this._added = true;
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
if (isString(pattern)) {
|
|
1286
|
+
pattern = {
|
|
1287
|
+
pattern
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
if (checkPattern(pattern.pattern)) {
|
|
1291
|
+
const rule = createRule(pattern, this._ignoreCase);
|
|
1292
|
+
this._added = true;
|
|
1293
|
+
this._rules.push(rule);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
// @param {Array<string> | string | Ignore} pattern
|
|
1297
|
+
add(pattern) {
|
|
1298
|
+
this._added = false;
|
|
1299
|
+
makeArray(
|
|
1300
|
+
isString(pattern) ? splitPattern(pattern) : pattern
|
|
1301
|
+
).forEach(this._add, this);
|
|
1302
|
+
return this._added;
|
|
1303
|
+
}
|
|
1304
|
+
// Test one single path without recursively checking parent directories
|
|
1305
|
+
//
|
|
1306
|
+
// - checkUnignored `boolean` whether should check if the path is unignored,
|
|
1307
|
+
// setting `checkUnignored` to `false` could reduce additional
|
|
1308
|
+
// path matching.
|
|
1309
|
+
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
1310
|
+
// @returns {TestResult} true if a file is ignored
|
|
1311
|
+
test(path16, checkUnignored, mode) {
|
|
1312
|
+
let ignored = false;
|
|
1313
|
+
let unignored = false;
|
|
1314
|
+
let matchedRule;
|
|
1315
|
+
this._rules.forEach((rule) => {
|
|
1316
|
+
const { negative } = rule;
|
|
1317
|
+
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
const matched = rule[mode].test(path16);
|
|
1321
|
+
if (!matched) {
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
ignored = !negative;
|
|
1325
|
+
unignored = negative;
|
|
1326
|
+
matchedRule = negative ? UNDEFINED : rule;
|
|
1327
|
+
});
|
|
1328
|
+
const ret = {
|
|
1329
|
+
ignored,
|
|
1330
|
+
unignored
|
|
1331
|
+
};
|
|
1332
|
+
if (matchedRule) {
|
|
1333
|
+
ret.rule = matchedRule;
|
|
1334
|
+
}
|
|
1335
|
+
return ret;
|
|
1336
|
+
}
|
|
1337
|
+
};
|
|
1338
|
+
var throwError = (message, Ctor) => {
|
|
1339
|
+
throw new Ctor(message);
|
|
1340
|
+
};
|
|
1341
|
+
var checkPath = (path16, originalPath, doThrow) => {
|
|
1342
|
+
if (!isString(path16)) {
|
|
1343
|
+
return doThrow(
|
|
1344
|
+
`path must be a string, but got \`${originalPath}\``,
|
|
1345
|
+
TypeError
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
if (!path16) {
|
|
1349
|
+
return doThrow(`path must not be empty`, TypeError);
|
|
1350
|
+
}
|
|
1351
|
+
if (checkPath.isNotRelative(path16)) {
|
|
1352
|
+
const r = "`path.relative()`d";
|
|
1353
|
+
return doThrow(
|
|
1354
|
+
`path should be a ${r} string, but got "${originalPath}"`,
|
|
1355
|
+
RangeError
|
|
1356
|
+
);
|
|
1357
|
+
}
|
|
1358
|
+
return true;
|
|
1359
|
+
};
|
|
1360
|
+
var isNotRelative = (path16) => REGEX_TEST_INVALID_PATH.test(path16);
|
|
1361
|
+
checkPath.isNotRelative = isNotRelative;
|
|
1362
|
+
checkPath.convert = (p) => p;
|
|
1363
|
+
var Ignore = class {
|
|
1364
|
+
constructor({
|
|
1365
|
+
ignorecase = true,
|
|
1366
|
+
ignoreCase = ignorecase,
|
|
1367
|
+
allowRelativePaths = false
|
|
1368
|
+
} = {}) {
|
|
1369
|
+
define(this, KEY_IGNORE, true);
|
|
1370
|
+
this._rules = new RuleManager(ignoreCase);
|
|
1371
|
+
this._strictPathCheck = !allowRelativePaths;
|
|
1372
|
+
this._initCache();
|
|
1373
|
+
}
|
|
1374
|
+
_initCache() {
|
|
1375
|
+
this._ignoreCache = /* @__PURE__ */ Object.create(null);
|
|
1376
|
+
this._testCache = /* @__PURE__ */ Object.create(null);
|
|
1377
|
+
}
|
|
1378
|
+
add(pattern) {
|
|
1379
|
+
if (this._rules.add(pattern)) {
|
|
1380
|
+
this._initCache();
|
|
1381
|
+
}
|
|
1382
|
+
return this;
|
|
1383
|
+
}
|
|
1384
|
+
// legacy
|
|
1385
|
+
addPattern(pattern) {
|
|
1386
|
+
return this.add(pattern);
|
|
1387
|
+
}
|
|
1388
|
+
// @returns {TestResult}
|
|
1389
|
+
_test(originalPath, cache, checkUnignored, slices) {
|
|
1390
|
+
const path16 = originalPath && checkPath.convert(originalPath);
|
|
1391
|
+
checkPath(
|
|
1392
|
+
path16,
|
|
1393
|
+
originalPath,
|
|
1394
|
+
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
1395
|
+
);
|
|
1396
|
+
return this._t(path16, cache, checkUnignored, slices);
|
|
1397
|
+
}
|
|
1398
|
+
checkIgnore(path16) {
|
|
1399
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path16)) {
|
|
1400
|
+
return this.test(path16);
|
|
1401
|
+
}
|
|
1402
|
+
const slices = path16.split(SLASH).filter(Boolean);
|
|
1403
|
+
slices.pop();
|
|
1404
|
+
if (slices.length) {
|
|
1405
|
+
const parent = this._t(
|
|
1406
|
+
slices.join(SLASH) + SLASH,
|
|
1407
|
+
this._testCache,
|
|
1408
|
+
true,
|
|
1409
|
+
slices
|
|
1410
|
+
);
|
|
1411
|
+
if (parent.ignored) {
|
|
1412
|
+
return parent;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
return this._rules.test(path16, false, MODE_CHECK_IGNORE);
|
|
1416
|
+
}
|
|
1417
|
+
_t(path16, cache, checkUnignored, slices) {
|
|
1418
|
+
if (path16 in cache) {
|
|
1419
|
+
return cache[path16];
|
|
1420
|
+
}
|
|
1421
|
+
if (!slices) {
|
|
1422
|
+
slices = path16.split(SLASH).filter(Boolean);
|
|
1423
|
+
}
|
|
1424
|
+
slices.pop();
|
|
1425
|
+
if (!slices.length) {
|
|
1426
|
+
return cache[path16] = this._rules.test(path16, checkUnignored, MODE_IGNORE);
|
|
1427
|
+
}
|
|
1428
|
+
const parent = this._t(
|
|
1429
|
+
slices.join(SLASH) + SLASH,
|
|
1430
|
+
cache,
|
|
1431
|
+
checkUnignored,
|
|
1432
|
+
slices
|
|
1433
|
+
);
|
|
1434
|
+
return cache[path16] = parent.ignored ? parent : this._rules.test(path16, checkUnignored, MODE_IGNORE);
|
|
1435
|
+
}
|
|
1436
|
+
ignores(path16) {
|
|
1437
|
+
return this._test(path16, this._ignoreCache, false).ignored;
|
|
1438
|
+
}
|
|
1439
|
+
createFilter() {
|
|
1440
|
+
return (path16) => !this.ignores(path16);
|
|
1441
|
+
}
|
|
1442
|
+
filter(paths) {
|
|
1443
|
+
return makeArray(paths).filter(this.createFilter());
|
|
1444
|
+
}
|
|
1445
|
+
// @returns {TestResult}
|
|
1446
|
+
test(path16) {
|
|
1447
|
+
return this._test(path16, this._testCache, true);
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
var factory = (options) => new Ignore(options);
|
|
1451
|
+
var isPathValid = (path16) => checkPath(path16 && checkPath.convert(path16), path16, RETURN_FALSE);
|
|
1452
|
+
var setupWindows = () => {
|
|
1453
|
+
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
1454
|
+
checkPath.convert = makePosix;
|
|
1455
|
+
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
1456
|
+
checkPath.isNotRelative = (path16) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path16) || isNotRelative(path16);
|
|
1457
|
+
};
|
|
1458
|
+
if (
|
|
1459
|
+
// Detect `process` so that it can run in browsers.
|
|
1460
|
+
typeof process !== "undefined" && process.platform === "win32"
|
|
1461
|
+
) {
|
|
1462
|
+
setupWindows();
|
|
1463
|
+
}
|
|
1464
|
+
module.exports = factory;
|
|
1465
|
+
factory.default = factory;
|
|
1466
|
+
module.exports.isPathValid = isPathValid;
|
|
1467
|
+
define(module.exports, Symbol.for("setupWindows"), setupWindows);
|
|
1468
|
+
}
|
|
1469
|
+
});
|
|
1470
|
+
|
|
1471
|
+
// src/code-nav/gitignore-filter.ts
|
|
1472
|
+
import fs10 from "node:fs";
|
|
1473
|
+
import path10 from "node:path";
|
|
1474
|
+
function normalizeRelPath(relPath) {
|
|
1475
|
+
return relPath.replace(/\\/g, "/");
|
|
1476
|
+
}
|
|
1477
|
+
function isUnderDir(relPath, dirRel) {
|
|
1478
|
+
return relPath === dirRel || relPath.startsWith(`${dirRel}/`);
|
|
1479
|
+
}
|
|
1480
|
+
async function createGitignoreFilterForRelativePath(root, relPath) {
|
|
1481
|
+
const filter = new GitignoreFilter();
|
|
1482
|
+
await filter.enterDirectory(root, "");
|
|
1483
|
+
const dirRel = normalizeRelPath(path10.dirname(relPath));
|
|
1484
|
+
if (dirRel === "." || dirRel === "") return filter;
|
|
1485
|
+
let abs = root;
|
|
1486
|
+
let rel = "";
|
|
1487
|
+
for (const segment of dirRel.split("/")) {
|
|
1488
|
+
abs = path10.join(abs, segment);
|
|
1489
|
+
rel = rel ? `${rel}/${segment}` : segment;
|
|
1490
|
+
await filter.enterDirectory(abs, rel);
|
|
1491
|
+
}
|
|
1492
|
+
return filter;
|
|
1493
|
+
}
|
|
1494
|
+
async function isPathGitIgnored(root, relPath) {
|
|
1495
|
+
const normalized = normalizeRelPath(relPath);
|
|
1496
|
+
const filter = await createGitignoreFilterForRelativePath(root, normalized);
|
|
1497
|
+
return filter.isIgnored(normalized);
|
|
1498
|
+
}
|
|
1499
|
+
var import_ignore, DEFAULT_IGNORED, GitignoreFilter;
|
|
1500
|
+
var init_gitignore_filter = __esm({
|
|
1501
|
+
"src/code-nav/gitignore-filter.ts"() {
|
|
1502
|
+
"use strict";
|
|
1503
|
+
import_ignore = __toESM(require_ignore(), 1);
|
|
1504
|
+
DEFAULT_IGNORED = [".git", ".git/**"];
|
|
1505
|
+
GitignoreFilter = class {
|
|
1506
|
+
layers = [{ dirRel: "", ig: (0, import_ignore.default)().add(DEFAULT_IGNORED) }];
|
|
1507
|
+
/** Load `.gitignore` in `absDir` and push a layer when the file exists. */
|
|
1508
|
+
async enterDirectory(absDir, dirRel) {
|
|
1509
|
+
try {
|
|
1510
|
+
const content = await fs10.promises.readFile(path10.join(absDir, ".gitignore"), "utf8");
|
|
1511
|
+
this.layers.push({ dirRel, ig: (0, import_ignore.default)().add(content) });
|
|
1512
|
+
} catch {
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
/** Pop the ignore layer for `dirRel` when leaving that directory during a walk. */
|
|
1516
|
+
leaveDirectory(dirRel) {
|
|
1517
|
+
const top = this.layers[this.layers.length - 1];
|
|
1518
|
+
if (top != null && top.dirRel === dirRel) {
|
|
1519
|
+
this.layers.pop();
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
isIgnored(relPath, opts) {
|
|
1523
|
+
const normalized = normalizeRelPath(relPath);
|
|
1524
|
+
const checkPath = opts?.directory && !normalized.endsWith("/") ? `${normalized}/` : normalized;
|
|
1525
|
+
for (const layer of this.layers) {
|
|
1526
|
+
if (layer.dirRel !== "" && !isUnderDir(normalized, layer.dirRel)) continue;
|
|
1527
|
+
const local = layer.dirRel === "" ? checkPath : checkPath.slice(layer.dirRel.length + 1);
|
|
1528
|
+
if (local !== "" && layer.ig.ignores(local)) return true;
|
|
1529
|
+
}
|
|
1530
|
+
return false;
|
|
1531
|
+
}
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
});
|
|
1535
|
+
|
|
1536
|
+
// src/code-nav/language-registry.ts
|
|
1537
|
+
import path11 from "node:path";
|
|
1538
|
+
function languageAssetPaths(key, wasmFile) {
|
|
1539
|
+
return {
|
|
1540
|
+
wasmFile,
|
|
1541
|
+
tagsQueryFile: `tree-sitter-${key}/tags.scm`
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
function getLanguageKeyForFilePath(filePath) {
|
|
1545
|
+
const ext = path11.extname(filePath).replace(/^\./, "").toLowerCase();
|
|
1546
|
+
if (!ext) return null;
|
|
1547
|
+
return EXT_TO_LANGUAGE_KEY[ext] ?? null;
|
|
1548
|
+
}
|
|
1549
|
+
function getLanguageSpec(languageKey) {
|
|
1550
|
+
return LANGUAGE_SPECS[languageKey] ?? null;
|
|
1551
|
+
}
|
|
1552
|
+
function isCodeNavSupportedPath(filePath) {
|
|
1553
|
+
const key = getLanguageKeyForFilePath(filePath);
|
|
1554
|
+
return key != null && getLanguageSpec(key) != null;
|
|
1555
|
+
}
|
|
1556
|
+
var EXT_TO_LANGUAGE_KEY, LANGUAGE_SPECS;
|
|
1557
|
+
var init_language_registry = __esm({
|
|
1558
|
+
"src/code-nav/language-registry.ts"() {
|
|
1559
|
+
"use strict";
|
|
1560
|
+
EXT_TO_LANGUAGE_KEY = {
|
|
1561
|
+
js: "javascript",
|
|
1562
|
+
jsx: "javascript",
|
|
1563
|
+
mjs: "javascript",
|
|
1564
|
+
cjs: "javascript",
|
|
1565
|
+
ts: "typescript",
|
|
1566
|
+
tsx: "tsx",
|
|
1567
|
+
py: "python",
|
|
1568
|
+
go: "go",
|
|
1569
|
+
rs: "rust",
|
|
1570
|
+
rb: "ruby",
|
|
1571
|
+
java: "java",
|
|
1572
|
+
c: "c",
|
|
1573
|
+
h: "c",
|
|
1574
|
+
cpp: "cpp",
|
|
1575
|
+
cc: "cpp",
|
|
1576
|
+
cxx: "cpp",
|
|
1577
|
+
hpp: "cpp"
|
|
1578
|
+
};
|
|
1579
|
+
LANGUAGE_SPECS = {
|
|
1580
|
+
javascript: languageAssetPaths("javascript", "tree-sitter-javascript.wasm"),
|
|
1581
|
+
typescript: languageAssetPaths("typescript", "tree-sitter-typescript.wasm"),
|
|
1582
|
+
tsx: languageAssetPaths("typescript", "tree-sitter-tsx.wasm"),
|
|
1583
|
+
python: languageAssetPaths("python", "tree-sitter-python.wasm"),
|
|
1584
|
+
go: languageAssetPaths("go", "tree-sitter-go.wasm"),
|
|
1585
|
+
rust: languageAssetPaths("rust", "tree-sitter-rust.wasm"),
|
|
1586
|
+
ruby: languageAssetPaths("ruby", "tree-sitter-ruby.wasm"),
|
|
1587
|
+
java: languageAssetPaths("java", "tree-sitter-java.wasm"),
|
|
1588
|
+
c: languageAssetPaths("c", "tree-sitter-c.wasm"),
|
|
1589
|
+
cpp: languageAssetPaths("cpp", "tree-sitter-cpp.wasm")
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
});
|
|
1593
|
+
|
|
1594
|
+
// src/code-nav/walk-code-nav-files.ts
|
|
1595
|
+
import fs11 from "node:fs";
|
|
1596
|
+
import path12 from "node:path";
|
|
1597
|
+
async function walkCodeNavFilesInDirectory(dir, baseDir, relDir, filter, onFile, state) {
|
|
1598
|
+
await filter.enterDirectory(dir, relDir);
|
|
1599
|
+
let names;
|
|
1600
|
+
try {
|
|
1601
|
+
names = await fs11.promises.readdir(dir);
|
|
1602
|
+
} catch {
|
|
1603
|
+
filter.leaveDirectory(relDir);
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
for (const name of names) {
|
|
1607
|
+
if (shouldSkipWorkspaceWalkEntry(name)) continue;
|
|
1608
|
+
if (state.n > 0 && state.n % INDEX_WORK_YIELD_EVERY === 0) {
|
|
1609
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
1610
|
+
await yieldForBridgeInteractivePriority();
|
|
1611
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
1612
|
+
}
|
|
1613
|
+
state.n++;
|
|
1614
|
+
const relPath = relDir ? `${relDir}/${name}` : name;
|
|
1615
|
+
const full = path12.join(dir, name);
|
|
1616
|
+
let stat;
|
|
1617
|
+
try {
|
|
1618
|
+
stat = await fs11.promises.stat(full);
|
|
1619
|
+
} catch {
|
|
1620
|
+
continue;
|
|
1621
|
+
}
|
|
1622
|
+
if (stat.isDirectory()) {
|
|
1623
|
+
if (filter.isIgnored(relPath, { directory: true })) continue;
|
|
1624
|
+
await walkCodeNavFilesInDirectory(full, baseDir, relPath, filter, onFile, state);
|
|
1625
|
+
continue;
|
|
1626
|
+
}
|
|
1627
|
+
if (!stat.isFile()) continue;
|
|
1628
|
+
if (filter.isIgnored(relPath)) continue;
|
|
1629
|
+
if (!isCodeNavSupportedPath(relPath)) continue;
|
|
1630
|
+
await Promise.resolve(onFile(relPath));
|
|
1631
|
+
}
|
|
1632
|
+
filter.leaveDirectory(relDir);
|
|
1633
|
+
}
|
|
1634
|
+
async function walkCodeNavFilesAsync(rootDir, onFile, state = createWalkYieldState()) {
|
|
1635
|
+
const resolved = path12.resolve(rootDir);
|
|
1636
|
+
const filter = new GitignoreFilter();
|
|
1637
|
+
await walkCodeNavFilesInDirectory(resolved, resolved, "", filter, onFile, state);
|
|
1638
|
+
}
|
|
1639
|
+
var init_walk_code_nav_files = __esm({
|
|
1640
|
+
"src/code-nav/walk-code-nav-files.ts"() {
|
|
1641
|
+
"use strict";
|
|
1642
|
+
init_walk_workspace_tree();
|
|
1643
|
+
init_file_browser_in_flight();
|
|
1644
|
+
init_cli_process_interrupt();
|
|
1645
|
+
init_cli_database();
|
|
1646
|
+
init_constants();
|
|
1647
|
+
init_gitignore_filter();
|
|
1648
|
+
init_language_registry();
|
|
1649
|
+
}
|
|
1650
|
+
});
|
|
1651
|
+
|
|
1652
|
+
// src/code-nav/symbol-index/sqlite/symbol-index-version.ts
|
|
1653
|
+
var SYMBOL_INDEX_VERSION;
|
|
1654
|
+
var init_symbol_index_version = __esm({
|
|
1655
|
+
"src/code-nav/symbol-index/sqlite/symbol-index-version.ts"() {
|
|
1656
|
+
"use strict";
|
|
1657
|
+
SYMBOL_INDEX_VERSION = 11;
|
|
1658
|
+
}
|
|
1659
|
+
});
|
|
1660
|
+
|
|
1661
|
+
// src/files/cwd/bridge-root.ts
|
|
1662
|
+
function getBridgeRoot() {
|
|
1663
|
+
if (bridgeRootPath == null) {
|
|
1664
|
+
bridgeRootPath = normalizeResolvedPath(process.cwd());
|
|
1665
|
+
}
|
|
1666
|
+
return bridgeRootPath;
|
|
1667
|
+
}
|
|
1668
|
+
var bridgeRootPath;
|
|
1669
|
+
var init_bridge_root = __esm({
|
|
1670
|
+
"src/files/cwd/bridge-root.ts"() {
|
|
1671
|
+
"use strict";
|
|
1672
|
+
init_normalize_resolved_path();
|
|
1673
|
+
bridgeRootPath = null;
|
|
1674
|
+
}
|
|
1675
|
+
});
|
|
1676
|
+
|
|
1677
|
+
// src/files/index/paths.ts
|
|
1678
|
+
import path13 from "node:path";
|
|
1679
|
+
import crypto from "node:crypto";
|
|
1680
|
+
function getCwdHashForFileIndex(resolvedCwd) {
|
|
1681
|
+
return crypto.createHash("sha256").update(path13.resolve(resolvedCwd)).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
1682
|
+
}
|
|
1683
|
+
var init_paths2 = __esm({
|
|
1684
|
+
"src/files/index/paths.ts"() {
|
|
1685
|
+
"use strict";
|
|
1686
|
+
init_constants();
|
|
1687
|
+
}
|
|
1688
|
+
});
|
|
1689
|
+
|
|
1690
|
+
// src/code-nav/symbol-index/sqlite/parent-path.ts
|
|
1691
|
+
function normalizeParentPath(resolved) {
|
|
1692
|
+
return normalizeResolvedPath(resolved);
|
|
1693
|
+
}
|
|
1694
|
+
function resolveParentKind(resolved) {
|
|
1695
|
+
return normalizeParentPath(resolved) === normalizeParentPath(getBridgeRoot()) ? "base" : "overlay";
|
|
1696
|
+
}
|
|
1697
|
+
function ensureBaseParentId(db) {
|
|
1698
|
+
const bridgeRoot = normalizeParentPath(getBridgeRoot());
|
|
1699
|
+
const existing = db.get("SELECT id FROM symbol_index_parent_path WHERE path = ?", [bridgeRoot]);
|
|
1700
|
+
if (existing != null) return Number(existing.id);
|
|
1701
|
+
return upsertSymbolIndexParentPath(db, bridgeRoot);
|
|
1702
|
+
}
|
|
1703
|
+
function upsertSymbolIndexParentPath(db, resolved) {
|
|
1704
|
+
const normalized = normalizeParentPath(resolved);
|
|
1705
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1706
|
+
const kind = resolveParentKind(normalized);
|
|
1707
|
+
const baseParentId = kind === "overlay" ? ensureBaseParentId(db) : null;
|
|
1708
|
+
db.run(
|
|
1709
|
+
`INSERT INTO symbol_index_parent_path (path, path_hash, updated_at, index_version, kind, base_parent_id)
|
|
1710
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1711
|
+
ON CONFLICT(path) DO UPDATE SET
|
|
1712
|
+
path_hash = excluded.path_hash,
|
|
1713
|
+
updated_at = excluded.updated_at,
|
|
1714
|
+
index_version = excluded.index_version,
|
|
1715
|
+
kind = excluded.kind,
|
|
1716
|
+
base_parent_id = excluded.base_parent_id`,
|
|
1717
|
+
[normalized, getCwdHashForFileIndex(normalized), now, SYMBOL_INDEX_VERSION, kind, baseParentId]
|
|
1718
|
+
);
|
|
1719
|
+
const row = db.get("SELECT id FROM symbol_index_parent_path WHERE path = ?", [normalized]);
|
|
1720
|
+
if (row == null) throw new Error(`Failed to upsert symbol index parent path: ${normalized}`);
|
|
1721
|
+
return Number(row.id);
|
|
1722
|
+
}
|
|
1723
|
+
function rowToSymbolIndexParentContext(row) {
|
|
1724
|
+
return {
|
|
1725
|
+
parentId: Number(row.id),
|
|
1726
|
+
path: row.path,
|
|
1727
|
+
kind: row.kind,
|
|
1728
|
+
baseParentId: row.base_parent_id != null ? Number(row.base_parent_id) : null
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
function getSymbolIndexParentContext(db, resolvedParentPath) {
|
|
1732
|
+
const row = db.get(
|
|
1733
|
+
`SELECT id, path, kind, base_parent_id
|
|
1734
|
+
FROM symbol_index_parent_path
|
|
1735
|
+
WHERE path = ?`,
|
|
1736
|
+
[normalizeParentPath(resolvedParentPath)]
|
|
1737
|
+
);
|
|
1738
|
+
if (row == null) return null;
|
|
1739
|
+
return rowToSymbolIndexParentContext(row);
|
|
1740
|
+
}
|
|
1741
|
+
var init_parent_path = __esm({
|
|
1742
|
+
"src/code-nav/symbol-index/sqlite/parent-path.ts"() {
|
|
1743
|
+
"use strict";
|
|
1744
|
+
init_bridge_root();
|
|
1745
|
+
init_paths2();
|
|
1746
|
+
init_normalize_resolved_path();
|
|
1747
|
+
init_code_nav_cache_database();
|
|
1748
|
+
init_symbol_index_version();
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
|
|
1752
|
+
// src/code-nav/symbol-index/storage/content-hash-check.ts
|
|
1753
|
+
function contentHashFileHasTags(db, contentHash, filePath) {
|
|
1754
|
+
const row = db.get(
|
|
1755
|
+
"SELECT 1 as ok FROM symbol_index_tag WHERE content_hash = ? AND file_path = ? LIMIT 1",
|
|
1756
|
+
[contentHash, filePath]
|
|
1757
|
+
);
|
|
1758
|
+
return row != null;
|
|
1759
|
+
}
|
|
1760
|
+
function contentHashFileHasImports(db, contentHash, filePath) {
|
|
1761
|
+
const row = db.get(
|
|
1762
|
+
"SELECT 1 as ok FROM symbol_index_import WHERE content_hash = ? AND file_path = ? LIMIT 1",
|
|
1763
|
+
[contentHash, filePath]
|
|
1764
|
+
);
|
|
1765
|
+
return row != null;
|
|
1766
|
+
}
|
|
1767
|
+
var init_content_hash_check = __esm({
|
|
1768
|
+
"src/code-nav/symbol-index/storage/content-hash-check.ts"() {
|
|
1769
|
+
"use strict";
|
|
1770
|
+
}
|
|
1771
|
+
});
|
|
1772
|
+
|
|
1773
|
+
// src/code-nav/symbol-index/storage/insert-symbol-content.ts
|
|
1774
|
+
function insertSymbolTagsForContent(db, contentHash, filePath, tags) {
|
|
1775
|
+
const ins = db.prepare(
|
|
1776
|
+
`INSERT OR IGNORE INTO symbol_index_tag
|
|
1777
|
+
(content_hash, file_path, name, role, kind, start_line, start_column, end_line, end_column,
|
|
1778
|
+
scope_start_line, scope_start_column, parent_scope_start_line, parent_scope_start_column,
|
|
1779
|
+
nav_target_path, scope_chain)
|
|
1780
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
1781
|
+
);
|
|
1782
|
+
try {
|
|
1783
|
+
for (const tag of tags) {
|
|
1784
|
+
ins.run([
|
|
1785
|
+
contentHash,
|
|
1786
|
+
filePath,
|
|
1787
|
+
tag.name,
|
|
1788
|
+
tag.role,
|
|
1789
|
+
tag.kind,
|
|
1790
|
+
tag.startLine,
|
|
1791
|
+
tag.startColumn,
|
|
1792
|
+
tag.endLine,
|
|
1793
|
+
tag.endColumn,
|
|
1794
|
+
tag.scopeStartLine ?? null,
|
|
1795
|
+
tag.scopeStartColumn ?? null,
|
|
1796
|
+
tag.parentScopeStartLine ?? null,
|
|
1797
|
+
tag.parentScopeStartColumn ?? null,
|
|
1798
|
+
tag.navTargetPath ?? null,
|
|
1799
|
+
tag.scopeChain ?? null
|
|
1800
|
+
]);
|
|
1801
|
+
}
|
|
1802
|
+
} finally {
|
|
1803
|
+
ins.finalize();
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
function insertSymbolImportsForContent(db, contentHash, filePath, imports) {
|
|
1807
|
+
const ins = db.prepare(
|
|
1808
|
+
`INSERT OR IGNORE INTO symbol_index_import
|
|
1809
|
+
(content_hash, file_path, local_name, source_name, module_specifier, source_file_path, import_kind, start_line, start_column)
|
|
1810
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
1811
|
+
);
|
|
1812
|
+
try {
|
|
1813
|
+
for (const binding of imports) {
|
|
1814
|
+
ins.run([
|
|
1815
|
+
contentHash,
|
|
1816
|
+
filePath,
|
|
1817
|
+
binding.localName,
|
|
1818
|
+
binding.sourceName,
|
|
1819
|
+
binding.moduleSpecifier,
|
|
1820
|
+
binding.sourceFilePath,
|
|
1821
|
+
binding.importKind,
|
|
1822
|
+
binding.startLine,
|
|
1823
|
+
binding.startColumn
|
|
1824
|
+
]);
|
|
1825
|
+
}
|
|
1826
|
+
} finally {
|
|
1827
|
+
ins.finalize();
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
var init_insert_symbol_content = __esm({
|
|
1831
|
+
"src/code-nav/symbol-index/storage/insert-symbol-content.ts"() {
|
|
1832
|
+
"use strict";
|
|
1833
|
+
}
|
|
1834
|
+
});
|
|
1835
|
+
|
|
1836
|
+
// src/code-nav/symbol-index/storage/parent-file-map.ts
|
|
1837
|
+
function getParentFileMapHash(db, parentId, filePath) {
|
|
1838
|
+
const row = db.get(
|
|
1839
|
+
"SELECT content_hash FROM symbol_parent_file_map WHERE parent_id = ? AND file_path = ?",
|
|
1840
|
+
[parentId, filePath]
|
|
1841
|
+
);
|
|
1842
|
+
if (row == null) return void 0;
|
|
1843
|
+
return row.content_hash;
|
|
1844
|
+
}
|
|
1845
|
+
function countParentFileMapRefs(db, contentHash) {
|
|
1846
|
+
const row = db.get("SELECT COUNT(*) as n FROM symbol_parent_file_map WHERE content_hash = ?", [
|
|
1847
|
+
contentHash
|
|
1848
|
+
]);
|
|
1849
|
+
return Number(row.n);
|
|
1850
|
+
}
|
|
1851
|
+
function setParentFileMapEntry(db, parentId, filePath, contentHash) {
|
|
1852
|
+
const previous = getParentFileMapHash(db, parentId, filePath);
|
|
1853
|
+
if (contentHash == null) {
|
|
1854
|
+
db.run(
|
|
1855
|
+
`INSERT INTO symbol_parent_file_map (parent_id, file_path, content_hash)
|
|
1856
|
+
VALUES (?, ?, NULL)
|
|
1857
|
+
ON CONFLICT(parent_id, file_path) DO UPDATE SET content_hash = NULL`,
|
|
1858
|
+
[parentId, filePath]
|
|
1859
|
+
);
|
|
1860
|
+
} else {
|
|
1861
|
+
db.run(
|
|
1862
|
+
`INSERT INTO symbol_parent_file_map (parent_id, file_path, content_hash)
|
|
1863
|
+
VALUES (?, ?, ?)
|
|
1864
|
+
ON CONFLICT(parent_id, file_path) DO UPDATE SET content_hash = excluded.content_hash`,
|
|
1865
|
+
[parentId, filePath, contentHash]
|
|
1866
|
+
);
|
|
1867
|
+
}
|
|
1868
|
+
return previous === void 0 ? null : previous;
|
|
1869
|
+
}
|
|
1870
|
+
function removeParentFileMapEntry(db, parentId, filePath) {
|
|
1871
|
+
const previous = getParentFileMapHash(db, parentId, filePath);
|
|
1872
|
+
db.run("DELETE FROM symbol_parent_file_map WHERE parent_id = ? AND file_path = ?", [parentId, filePath]);
|
|
1873
|
+
return previous === void 0 ? null : previous;
|
|
1874
|
+
}
|
|
1875
|
+
function clearParentFileMapBatch(db, parentId, limit) {
|
|
1876
|
+
const rows = db.all(
|
|
1877
|
+
`SELECT file_path, content_hash
|
|
1878
|
+
FROM symbol_parent_file_map
|
|
1879
|
+
WHERE parent_id = ?
|
|
1880
|
+
LIMIT ?`,
|
|
1881
|
+
[parentId, limit]
|
|
1882
|
+
);
|
|
1883
|
+
if (rows.length === 0) return { released: [], remaining: false };
|
|
1884
|
+
const del = db.prepare("DELETE FROM symbol_parent_file_map WHERE parent_id = ? AND file_path = ?");
|
|
1885
|
+
try {
|
|
1886
|
+
for (const row of rows) {
|
|
1887
|
+
del.run([parentId, row.file_path]);
|
|
1888
|
+
}
|
|
1889
|
+
} finally {
|
|
1890
|
+
del.finalize();
|
|
1891
|
+
}
|
|
1892
|
+
return {
|
|
1893
|
+
released: rows.flatMap((row) => row.content_hash == null ? [] : [row.content_hash]),
|
|
1894
|
+
remaining: rows.length >= limit
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
var init_parent_file_map = __esm({
|
|
1898
|
+
"src/code-nav/symbol-index/storage/parent-file-map.ts"() {
|
|
1899
|
+
"use strict";
|
|
1900
|
+
}
|
|
1901
|
+
});
|
|
1902
|
+
|
|
1903
|
+
// src/code-nav/symbol-index/storage/symbol-content-index.ts
|
|
1904
|
+
function upsertSymbolContentIndex(db, contentHash, filePath, tags, imports) {
|
|
1905
|
+
if (tags.length > 0 && !contentHashFileHasTags(db, contentHash, filePath)) {
|
|
1906
|
+
insertSymbolTagsForContent(db, contentHash, filePath, tags);
|
|
1907
|
+
}
|
|
1908
|
+
if (imports.length > 0 && !contentHashFileHasImports(db, contentHash, filePath)) {
|
|
1909
|
+
insertSymbolImportsForContent(db, contentHash, filePath, imports);
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
function deleteSymbolContentIfUnreferenced(db, contentHash) {
|
|
1913
|
+
if (countParentFileMapRefs(db, contentHash) > 0) return;
|
|
1914
|
+
db.run("DELETE FROM symbol_index_tag WHERE content_hash = ?", [contentHash]);
|
|
1915
|
+
db.run("DELETE FROM symbol_index_import WHERE content_hash = ?", [contentHash]);
|
|
1916
|
+
}
|
|
1917
|
+
var init_symbol_content_index = __esm({
|
|
1918
|
+
"src/code-nav/symbol-index/storage/symbol-content-index.ts"() {
|
|
1919
|
+
"use strict";
|
|
1920
|
+
init_content_hash_check();
|
|
1921
|
+
init_insert_symbol_content();
|
|
1922
|
+
init_parent_file_map();
|
|
1923
|
+
}
|
|
1924
|
+
});
|
|
1925
|
+
|
|
1926
|
+
// src/code-nav/symbol-index/storage/effective-content.ts
|
|
1927
|
+
function getEffectiveContentHash(db, ctx, filePath) {
|
|
1928
|
+
const overlayHash = getParentFileMapHash(db, ctx.parentId, filePath);
|
|
1929
|
+
if (overlayHash !== void 0) return overlayHash;
|
|
1930
|
+
if (ctx.baseParentId == null) return null;
|
|
1931
|
+
const baseHash = getParentFileMapHash(db, ctx.baseParentId, filePath);
|
|
1932
|
+
if (baseHash === void 0) return null;
|
|
1933
|
+
return baseHash;
|
|
1934
|
+
}
|
|
1935
|
+
function listEffectiveIndexedFilePaths(db, ctx) {
|
|
1936
|
+
const paths = /* @__PURE__ */ new Set();
|
|
1937
|
+
if (ctx.baseParentId != null) {
|
|
1938
|
+
const baseRows = db.all("SELECT file_path FROM symbol_parent_file_map WHERE parent_id = ? AND content_hash IS NOT NULL", [
|
|
1939
|
+
ctx.baseParentId
|
|
1940
|
+
]);
|
|
1941
|
+
for (const row of baseRows) paths.add(row.file_path);
|
|
1942
|
+
}
|
|
1943
|
+
const overlayRows = db.all("SELECT file_path, content_hash FROM symbol_parent_file_map WHERE parent_id = ?", [
|
|
1944
|
+
ctx.parentId
|
|
1945
|
+
]);
|
|
1946
|
+
for (const row of overlayRows) {
|
|
1947
|
+
if (row.content_hash == null) paths.delete(row.file_path);
|
|
1948
|
+
else paths.add(row.file_path);
|
|
1949
|
+
}
|
|
1950
|
+
if (ctx.baseParentId == null) {
|
|
1951
|
+
const ownRows = db.all("SELECT file_path FROM symbol_parent_file_map WHERE parent_id = ? AND content_hash IS NOT NULL", [
|
|
1952
|
+
ctx.parentId
|
|
1953
|
+
]);
|
|
1954
|
+
for (const row of ownRows) paths.add(row.file_path);
|
|
1955
|
+
}
|
|
1956
|
+
return [...paths];
|
|
1957
|
+
}
|
|
1958
|
+
var init_effective_content = __esm({
|
|
1959
|
+
"src/code-nav/symbol-index/storage/effective-content.ts"() {
|
|
1960
|
+
"use strict";
|
|
1961
|
+
init_parent_file_map();
|
|
1962
|
+
}
|
|
1963
|
+
});
|
|
1964
|
+
|
|
1965
|
+
// src/code-nav/symbol-index/persistence/symbol-file-content-hash.ts
|
|
1966
|
+
import crypto2 from "node:crypto";
|
|
1967
|
+
function hashSymbolFileContent(source) {
|
|
1968
|
+
return crypto2.createHash("sha256").update(source ?? "").digest("hex");
|
|
1969
|
+
}
|
|
1970
|
+
var init_symbol_file_content_hash = __esm({
|
|
1971
|
+
"src/code-nav/symbol-index/persistence/symbol-file-content-hash.ts"() {
|
|
1972
|
+
"use strict";
|
|
1973
|
+
}
|
|
1974
|
+
});
|
|
1975
|
+
|
|
1976
|
+
// src/code-nav/symbol-index/sqlite/file-data-persistence.ts
|
|
1977
|
+
function gcReleasedHashes(db, hashes) {
|
|
1978
|
+
for (const hash of hashes) {
|
|
1979
|
+
if (hash != null) deleteSymbolContentIfUnreferenced(db, hash);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
function persistFileSymbolData(db, ctx, filePath, contentHash, tags, imports) {
|
|
1983
|
+
upsertSymbolContentIndex(db, contentHash, filePath, tags, imports);
|
|
1984
|
+
if (ctx.kind === "overlay" && ctx.baseParentId != null) {
|
|
1985
|
+
const baseHash = getParentFileMapHash(db, ctx.baseParentId, filePath);
|
|
1986
|
+
if (baseHash === contentHash) {
|
|
1987
|
+
const released2 = removeParentFileMapEntry(db, ctx.parentId, filePath);
|
|
1988
|
+
gcReleasedHashes(db, [released2]);
|
|
1989
|
+
return;
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
const released = setParentFileMapEntry(db, ctx.parentId, filePath, contentHash);
|
|
1993
|
+
gcReleasedHashes(db, [released]);
|
|
1994
|
+
}
|
|
1995
|
+
function persistSymbolIndexFileData(db, ctx, filePath, source, tags, imports) {
|
|
1996
|
+
const contentHash = hashSymbolFileContent(source);
|
|
1997
|
+
persistFileSymbolData(db, ctx, filePath, contentHash, tags, imports);
|
|
1998
|
+
}
|
|
1999
|
+
function removeSymbolIndexFileData(db, ctx, filePath) {
|
|
2000
|
+
if (ctx.kind === "overlay") {
|
|
2001
|
+
const released2 = setParentFileMapEntry(db, ctx.parentId, filePath, null);
|
|
2002
|
+
gcReleasedHashes(db, [released2]);
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
2005
|
+
const released = removeParentFileMapEntry(db, ctx.parentId, filePath);
|
|
2006
|
+
gcReleasedHashes(db, [released]);
|
|
2007
|
+
}
|
|
2008
|
+
function clearSymbolIndexParentDataBatch(db, ctx, limit) {
|
|
2009
|
+
const { released, remaining } = clearParentFileMapBatch(db, ctx.parentId, limit);
|
|
2010
|
+
gcReleasedHashes(db, released);
|
|
2011
|
+
return remaining;
|
|
2012
|
+
}
|
|
2013
|
+
var init_file_data_persistence = __esm({
|
|
2014
|
+
"src/code-nav/symbol-index/sqlite/file-data-persistence.ts"() {
|
|
2015
|
+
"use strict";
|
|
2016
|
+
init_symbol_content_index();
|
|
2017
|
+
init_effective_content();
|
|
2018
|
+
init_parent_file_map();
|
|
2019
|
+
init_symbol_file_content_hash();
|
|
2020
|
+
}
|
|
2021
|
+
});
|
|
2022
|
+
|
|
2023
|
+
// src/code-nav/symbol-index/sqlite/population.ts
|
|
2024
|
+
var init_population = __esm({
|
|
2025
|
+
"src/code-nav/symbol-index/sqlite/population.ts"() {
|
|
2026
|
+
"use strict";
|
|
2027
|
+
init_code_nav_cache_database();
|
|
2028
|
+
init_parent_path();
|
|
2029
|
+
init_symbol_index_version();
|
|
2030
|
+
}
|
|
2031
|
+
});
|
|
2032
|
+
|
|
2033
|
+
// src/code-nav/symbol-index/sqlite/symbol-index-sqlite.ts
|
|
2034
|
+
var init_symbol_index_sqlite = __esm({
|
|
2035
|
+
"src/code-nav/symbol-index/sqlite/symbol-index-sqlite.ts"() {
|
|
2036
|
+
"use strict";
|
|
2037
|
+
init_symbol_index_version();
|
|
2038
|
+
init_parent_path();
|
|
2039
|
+
init_file_data_persistence();
|
|
2040
|
+
init_population();
|
|
2041
|
+
}
|
|
2042
|
+
});
|
|
2043
|
+
|
|
2044
|
+
// src/code-nav/symbol-index/sqlite/symbol-index-sqlite-lock.ts
|
|
2045
|
+
function withSymbolIndexSqliteLock(fn) {
|
|
2046
|
+
return withCodeNavCacheSqliteWorkLock(fn);
|
|
2047
|
+
}
|
|
2048
|
+
var init_symbol_index_sqlite_lock = __esm({
|
|
2049
|
+
"src/code-nav/symbol-index/sqlite/symbol-index-sqlite-lock.ts"() {
|
|
2050
|
+
"use strict";
|
|
2051
|
+
init_code_nav_cache_sqlite_work_lock();
|
|
2052
|
+
}
|
|
2053
|
+
});
|
|
2054
|
+
|
|
2055
|
+
// src/code-nav/symbol-index/query/tag-query-shared.ts
|
|
2056
|
+
var TAG_SELECT;
|
|
2057
|
+
var init_tag_query_shared = __esm({
|
|
2058
|
+
"src/code-nav/symbol-index/query/tag-query-shared.ts"() {
|
|
2059
|
+
"use strict";
|
|
2060
|
+
TAG_SELECT = `file_path, name, role, kind, start_line, start_column, end_line, end_column,
|
|
2061
|
+
scope_start_line, scope_start_column, parent_scope_start_line, parent_scope_start_column, nav_target_path, scope_chain`;
|
|
2062
|
+
}
|
|
2063
|
+
});
|
|
2064
|
+
|
|
2065
|
+
// src/code-nav/symbol-index/storage/file-content-load.ts
|
|
2066
|
+
function loadFileTags(db, ctx, filePath) {
|
|
2067
|
+
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
2068
|
+
if (contentHash == null) return [];
|
|
2069
|
+
return db.all(
|
|
2070
|
+
`SELECT ${TAG_SELECT}
|
|
2071
|
+
FROM symbol_index_tag
|
|
2072
|
+
WHERE content_hash = ? AND file_path = ?
|
|
2073
|
+
ORDER BY start_line, start_column`,
|
|
2074
|
+
[contentHash, filePath]
|
|
2075
|
+
);
|
|
2076
|
+
}
|
|
2077
|
+
function loadFileImports(db, ctx, filePath) {
|
|
2078
|
+
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
2079
|
+
if (contentHash == null) return [];
|
|
2080
|
+
return db.all(
|
|
2081
|
+
`SELECT file_path, local_name, source_name, module_specifier, source_file_path, import_kind, start_line, start_column
|
|
2082
|
+
FROM symbol_index_import
|
|
2083
|
+
WHERE content_hash = ? AND file_path = ?
|
|
2084
|
+
ORDER BY start_line, start_column`,
|
|
2085
|
+
[contentHash, filePath]
|
|
2086
|
+
);
|
|
2087
|
+
}
|
|
2088
|
+
var init_file_content_load = __esm({
|
|
2089
|
+
"src/code-nav/symbol-index/storage/file-content-load.ts"() {
|
|
2090
|
+
"use strict";
|
|
2091
|
+
init_tag_query_shared();
|
|
2092
|
+
init_effective_content();
|
|
2093
|
+
}
|
|
2094
|
+
});
|
|
2095
|
+
|
|
2096
|
+
// src/code-nav/symbol-index/storage/symbol-parent-file-map.ts
|
|
2097
|
+
var init_symbol_parent_file_map = __esm({
|
|
2098
|
+
"src/code-nav/symbol-index/storage/symbol-parent-file-map.ts"() {
|
|
2099
|
+
"use strict";
|
|
2100
|
+
init_parent_file_map();
|
|
2101
|
+
init_effective_content();
|
|
2102
|
+
init_file_content_load();
|
|
2103
|
+
}
|
|
2104
|
+
});
|
|
2105
|
+
|
|
2106
|
+
// src/code-nav/symbol-index/build/load-indexed-file-entry.ts
|
|
2107
|
+
function dbTagToSymbolTag(row) {
|
|
2108
|
+
return {
|
|
2109
|
+
name: row.name,
|
|
2110
|
+
role: row.role,
|
|
2111
|
+
kind: row.kind,
|
|
2112
|
+
startLine: row.start_line,
|
|
2113
|
+
startColumn: row.start_column,
|
|
2114
|
+
endLine: row.end_line,
|
|
2115
|
+
endColumn: row.end_column,
|
|
2116
|
+
scopeStartLine: row.scope_start_line ?? void 0,
|
|
2117
|
+
scopeStartColumn: row.scope_start_column ?? void 0,
|
|
2118
|
+
parentScopeStartLine: row.parent_scope_start_line ?? void 0,
|
|
2119
|
+
parentScopeStartColumn: row.parent_scope_start_column ?? void 0,
|
|
2120
|
+
navTargetPath: row.nav_target_path ?? void 0,
|
|
2121
|
+
scopeChain: row.scope_chain ?? void 0
|
|
2122
|
+
};
|
|
2123
|
+
}
|
|
2124
|
+
function dbImportToSymbolImport(row) {
|
|
2125
|
+
return {
|
|
2126
|
+
localName: row.local_name,
|
|
2127
|
+
sourceName: row.source_name,
|
|
2128
|
+
moduleSpecifier: row.module_specifier,
|
|
2129
|
+
sourceFilePath: row.source_file_path,
|
|
2130
|
+
importKind: row.import_kind,
|
|
2131
|
+
startLine: row.start_line,
|
|
2132
|
+
startColumn: row.start_column
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
function loadIndexedFileEntry(db, ctx, relPath) {
|
|
2136
|
+
const tags = loadFileTags(db, ctx, relPath);
|
|
2137
|
+
const imports = loadFileImports(db, ctx, relPath);
|
|
2138
|
+
if (tags.length === 0 && imports.length === 0) return void 0;
|
|
2139
|
+
return {
|
|
2140
|
+
relPath,
|
|
2141
|
+
source: null,
|
|
2142
|
+
tags: tags.map(dbTagToSymbolTag),
|
|
2143
|
+
imports: imports.map(dbImportToSymbolImport)
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
var init_load_indexed_file_entry = __esm({
|
|
2147
|
+
"src/code-nav/symbol-index/build/load-indexed-file-entry.ts"() {
|
|
2148
|
+
"use strict";
|
|
2149
|
+
init_symbol_parent_file_map();
|
|
2150
|
+
}
|
|
2151
|
+
});
|
|
2152
|
+
|
|
2153
|
+
// src/code-nav/symbol-index/query/list-direct-import-targets.ts
|
|
2154
|
+
function normalizeRelPath2(filePath) {
|
|
2155
|
+
return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2156
|
+
}
|
|
2157
|
+
function listDirectImportTargetsWithDb(db, resolved, relPath) {
|
|
2158
|
+
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
2159
|
+
if (ctx == null) return [];
|
|
2160
|
+
const entry = loadIndexedFileEntry(db, ctx, relPath);
|
|
2161
|
+
if (entry == null) return [];
|
|
2162
|
+
const paths = /* @__PURE__ */ new Set();
|
|
2163
|
+
for (const binding of entry.imports) {
|
|
2164
|
+
if (binding.sourceFilePath) paths.add(binding.sourceFilePath);
|
|
2165
|
+
}
|
|
2166
|
+
return Array.from(paths);
|
|
2167
|
+
}
|
|
2168
|
+
async function listDirectImportTargetsForFileAsync(parentPath, filePath) {
|
|
2169
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
2170
|
+
const relPath = normalizeRelPath2(filePath);
|
|
2171
|
+
if (!relPath) return [];
|
|
2172
|
+
return withCodeNavCacheSqlite((db) => listDirectImportTargetsWithDb(db, resolved, relPath));
|
|
2173
|
+
}
|
|
2174
|
+
var init_list_direct_import_targets = __esm({
|
|
2175
|
+
"src/code-nav/symbol-index/query/list-direct-import-targets.ts"() {
|
|
2176
|
+
"use strict";
|
|
2177
|
+
init_normalize_resolved_path();
|
|
2178
|
+
init_code_nav_cache_database();
|
|
2179
|
+
init_load_indexed_file_entry();
|
|
2180
|
+
init_symbol_index_sqlite();
|
|
2181
|
+
}
|
|
2182
|
+
});
|
|
2183
|
+
|
|
2184
|
+
// src/code-nav/symbol-index/lifecycle/symbol-index-file-ready.ts
|
|
2185
|
+
function symbolIndexFileIsReadyWithDb(db, parentPath, filePath) {
|
|
2186
|
+
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
2187
|
+
const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2188
|
+
if (!normalizedFile) return false;
|
|
2189
|
+
const ctx = getSymbolIndexParentContext(db, normalizedParent);
|
|
2190
|
+
if (ctx == null) return false;
|
|
2191
|
+
const versionRow = db.get("SELECT index_version FROM symbol_index_parent_path WHERE id = ?", [
|
|
2192
|
+
ctx.parentId
|
|
2193
|
+
]);
|
|
2194
|
+
if (versionRow == null || versionRow.index_version < SYMBOL_INDEX_VERSION) return false;
|
|
2195
|
+
return getEffectiveContentHash(db, ctx, normalizedFile) != null;
|
|
2196
|
+
}
|
|
2197
|
+
async function symbolIndexFileIsReadyAsync(parentPath, filePath) {
|
|
2198
|
+
return withCodeNavCacheSqlite((db) => symbolIndexFileIsReadyWithDb(db, parentPath, filePath));
|
|
2199
|
+
}
|
|
2200
|
+
async function loadSymbolIndexReadyFileSet(parentPath) {
|
|
2201
|
+
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
2202
|
+
const paths = await withCodeNavCacheSqlite((db) => {
|
|
2203
|
+
const ctx = getSymbolIndexParentContext(db, normalizedParent);
|
|
2204
|
+
if (ctx == null) return [];
|
|
2205
|
+
const versionRow = db.get("SELECT index_version FROM symbol_index_parent_path WHERE id = ?", [
|
|
2206
|
+
ctx.parentId
|
|
2207
|
+
]);
|
|
2208
|
+
if (versionRow == null || versionRow.index_version < SYMBOL_INDEX_VERSION) return [];
|
|
2209
|
+
return listEffectiveIndexedFilePaths(db, ctx);
|
|
2210
|
+
});
|
|
2211
|
+
return new Set(paths);
|
|
2212
|
+
}
|
|
2213
|
+
var init_symbol_index_file_ready = __esm({
|
|
2214
|
+
"src/code-nav/symbol-index/lifecycle/symbol-index-file-ready.ts"() {
|
|
2215
|
+
"use strict";
|
|
2216
|
+
init_normalize_resolved_path();
|
|
2217
|
+
init_code_nav_cache_database();
|
|
2218
|
+
init_symbol_index_sqlite();
|
|
2219
|
+
init_symbol_parent_file_map();
|
|
2220
|
+
}
|
|
2221
|
+
});
|
|
2222
|
+
|
|
2223
|
+
// src/code-nav/symbol-index/imports/star-reexport-names.ts
|
|
2224
|
+
function isModuleLevelDef(tag) {
|
|
2225
|
+
return tag.role === "def" && tag.parentScopeStartLine == null && tag.parentScopeStartColumn == null;
|
|
2226
|
+
}
|
|
2227
|
+
function collectExportableNamesFromTags(tags) {
|
|
2228
|
+
const names = /* @__PURE__ */ new Map();
|
|
2229
|
+
for (const tag of tags) {
|
|
2230
|
+
if (!isModuleLevelDef(tag)) continue;
|
|
2231
|
+
if (!names.has(tag.name)) names.set(tag.name, tag.name);
|
|
2232
|
+
}
|
|
2233
|
+
return names;
|
|
2234
|
+
}
|
|
2235
|
+
function existingLocalNames(imports) {
|
|
2236
|
+
return new Set(imports.map((binding) => binding.localName));
|
|
2237
|
+
}
|
|
2238
|
+
function resolveExportableNames(filePath, entriesByPath, visited) {
|
|
2239
|
+
if (visited.has(filePath)) return /* @__PURE__ */ new Map();
|
|
2240
|
+
visited.add(filePath);
|
|
2241
|
+
const entry = entriesByPath.get(filePath);
|
|
2242
|
+
if (!entry) return /* @__PURE__ */ new Map();
|
|
2243
|
+
const out = collectExportableNamesFromTags(entry.tags);
|
|
2244
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
2245
|
+
for (const [name, sourceName] of out) {
|
|
2246
|
+
resolved.set(name, { sourceName, sourceFilePath: filePath });
|
|
2247
|
+
}
|
|
2248
|
+
for (const binding of entry.imports) {
|
|
2249
|
+
if (binding.importKind !== "star" || !binding.sourceFilePath) continue;
|
|
2250
|
+
const upstream = resolveExportableNames(binding.sourceFilePath, entriesByPath, visited);
|
|
2251
|
+
for (const [name, info] of upstream) {
|
|
2252
|
+
if (!resolved.has(name)) resolved.set(name, info);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
for (const binding of entry.imports) {
|
|
2256
|
+
if (binding.importKind !== "reexport" && binding.importKind !== "type") continue;
|
|
2257
|
+
if (!binding.sourceFilePath) continue;
|
|
2258
|
+
if (!resolved.has(binding.localName)) {
|
|
2259
|
+
resolved.set(binding.localName, {
|
|
2260
|
+
sourceName: binding.sourceName,
|
|
2261
|
+
sourceFilePath: binding.sourceFilePath
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
return resolved;
|
|
2266
|
+
}
|
|
2267
|
+
var STAR_LOCAL_NAME;
|
|
2268
|
+
var init_star_reexport_names = __esm({
|
|
2269
|
+
"src/code-nav/symbol-index/imports/star-reexport-names.ts"() {
|
|
2270
|
+
"use strict";
|
|
2271
|
+
STAR_LOCAL_NAME = "*";
|
|
2272
|
+
}
|
|
2273
|
+
});
|
|
2274
|
+
|
|
2275
|
+
// src/code-nav/symbol-index/imports/star-reexport-upstream.ts
|
|
2276
|
+
function collectUpstreamEntries(entry, resolveEntry) {
|
|
2277
|
+
const entriesByPath = /* @__PURE__ */ new Map();
|
|
2278
|
+
entriesByPath.set(entry.relPath, entry);
|
|
2279
|
+
const visit = (filePath, visited) => {
|
|
2280
|
+
if (visited.has(filePath)) return;
|
|
2281
|
+
visited.add(filePath);
|
|
2282
|
+
const resolved = resolveEntry(filePath);
|
|
2283
|
+
if (resolved == null) return;
|
|
2284
|
+
entriesByPath.set(filePath, resolved);
|
|
2285
|
+
for (const binding of resolved.imports) {
|
|
2286
|
+
if (binding.sourceFilePath) visit(binding.sourceFilePath, visited);
|
|
2287
|
+
}
|
|
2288
|
+
};
|
|
2289
|
+
for (const star of entry.imports) {
|
|
2290
|
+
if (star.importKind !== "star" || !star.sourceFilePath) continue;
|
|
2291
|
+
visit(star.sourceFilePath, /* @__PURE__ */ new Set());
|
|
2292
|
+
}
|
|
2293
|
+
return [...entriesByPath.values()];
|
|
2294
|
+
}
|
|
2295
|
+
var init_star_reexport_upstream = __esm({
|
|
2296
|
+
"src/code-nav/symbol-index/imports/star-reexport-upstream.ts"() {
|
|
2297
|
+
"use strict";
|
|
2298
|
+
}
|
|
2299
|
+
});
|
|
2300
|
+
|
|
2301
|
+
// src/code-nav/symbol-index/imports/expand-star-reexports.ts
|
|
2302
|
+
function expandStarReexportForFile(entry, resolveEntry) {
|
|
2303
|
+
const collected = collectUpstreamEntries(entry, resolveEntry);
|
|
2304
|
+
return expandStarReexportBindings(collected).find((row) => row.relPath === entry.relPath) ?? entry;
|
|
2305
|
+
}
|
|
2306
|
+
function expandStarReexportBindings(collected) {
|
|
2307
|
+
const entriesByPath = new Map(collected.map((entry) => [entry.relPath, entry]));
|
|
2308
|
+
return collected.map((entry) => {
|
|
2309
|
+
const stars = entry.imports.filter((binding) => binding.importKind === "star");
|
|
2310
|
+
if (stars.length === 0) return entry;
|
|
2311
|
+
const localNames = existingLocalNames(entry.imports);
|
|
2312
|
+
const materialized = [];
|
|
2313
|
+
for (const star of stars) {
|
|
2314
|
+
if (!star.sourceFilePath) continue;
|
|
2315
|
+
const exportable = resolveExportableNames(star.sourceFilePath, entriesByPath, /* @__PURE__ */ new Set());
|
|
2316
|
+
for (const [localName, info] of exportable) {
|
|
2317
|
+
if (localName === STAR_LOCAL_NAME || localNames.has(localName)) continue;
|
|
2318
|
+
localNames.add(localName);
|
|
2319
|
+
materialized.push({
|
|
2320
|
+
localName,
|
|
2321
|
+
sourceName: info.sourceName,
|
|
2322
|
+
moduleSpecifier: star.moduleSpecifier,
|
|
2323
|
+
sourceFilePath: info.sourceFilePath,
|
|
2324
|
+
importKind: star.importKind === "type" ? "type" : "reexport",
|
|
2325
|
+
startLine: star.startLine,
|
|
2326
|
+
startColumn: star.startColumn
|
|
2327
|
+
});
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
if (materialized.length === 0) return entry;
|
|
2331
|
+
return { ...entry, imports: [...entry.imports, ...materialized] };
|
|
2332
|
+
});
|
|
2333
|
+
}
|
|
2334
|
+
var init_expand_star_reexports = __esm({
|
|
2335
|
+
"src/code-nav/symbol-index/imports/expand-star-reexports.ts"() {
|
|
2336
|
+
"use strict";
|
|
2337
|
+
init_star_reexport_names();
|
|
2338
|
+
init_star_reexport_upstream();
|
|
2339
|
+
}
|
|
2340
|
+
});
|
|
2341
|
+
|
|
2342
|
+
// src/code-nav/symbol-index/persistence/persist-single-file.ts
|
|
2343
|
+
async function persistSymbolIndexFileAsync(resolved, relPath, source, tags, imports) {
|
|
2344
|
+
await withCodeNavCacheSqlite(async (db) => {
|
|
2345
|
+
runCodeNavCacheWriteTransaction(db, () => {
|
|
2346
|
+
upsertSymbolIndexParentPath(db, resolved);
|
|
2347
|
+
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
2348
|
+
if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
|
|
2349
|
+
persistSymbolIndexFileData(db, ctx, relPath, source, tags, imports);
|
|
2350
|
+
});
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
async function removeSymbolIndexFileAsync(resolved, relPath) {
|
|
2354
|
+
await withCodeNavCacheSqlite(async (db) => {
|
|
2355
|
+
runCodeNavCacheWriteTransaction(db, () => {
|
|
2356
|
+
upsertSymbolIndexParentPath(db, resolved);
|
|
2357
|
+
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
2358
|
+
if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
|
|
2359
|
+
removeSymbolIndexFileData(db, ctx, relPath);
|
|
2360
|
+
});
|
|
2361
|
+
});
|
|
2362
|
+
}
|
|
2363
|
+
var init_persist_single_file = __esm({
|
|
2364
|
+
"src/code-nav/symbol-index/persistence/persist-single-file.ts"() {
|
|
2365
|
+
"use strict";
|
|
2366
|
+
init_code_nav_cache_database();
|
|
2367
|
+
init_code_nav_cache_sqlite_transaction();
|
|
2368
|
+
init_symbol_index_sqlite();
|
|
2369
|
+
}
|
|
2370
|
+
});
|
|
2371
|
+
|
|
2372
|
+
// src/code-nav/resolve-module-import-path.ts
|
|
2373
|
+
import path14 from "node:path";
|
|
2374
|
+
function normalizeWorkspacePath(filePath) {
|
|
2375
|
+
return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2376
|
+
}
|
|
2377
|
+
function isRelativeModuleSpecifier(specifier) {
|
|
2378
|
+
return specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/");
|
|
2379
|
+
}
|
|
2380
|
+
function firstExistingPath(candidates, workspaceFiles) {
|
|
2381
|
+
for (const candidate of candidates) {
|
|
2382
|
+
const normalized = normalizeWorkspacePath(candidate);
|
|
2383
|
+
if (workspaceFiles.has(normalized)) return normalized;
|
|
2384
|
+
}
|
|
2385
|
+
return null;
|
|
2386
|
+
}
|
|
2387
|
+
function withSuffixes(basePath, suffixes) {
|
|
2388
|
+
return suffixes.map((suffix) => basePath + suffix);
|
|
2389
|
+
}
|
|
2390
|
+
function tsJsImportCandidates(joined) {
|
|
2391
|
+
const candidates = withSuffixes(joined, TS_JS_EXTENSIONS);
|
|
2392
|
+
const extensionRewrites = [
|
|
2393
|
+
[".js", [".ts", ".tsx", ".js", ".jsx"]],
|
|
2394
|
+
[".jsx", [".tsx", ".ts", ".jsx", ".js"]],
|
|
2395
|
+
[".mjs", [".mts", ".ts", ".mjs", ".js"]],
|
|
2396
|
+
[".cjs", [".cts", ".ts", ".cjs", ".js"]]
|
|
2397
|
+
];
|
|
2398
|
+
for (const [fromExt, toExts] of extensionRewrites) {
|
|
2399
|
+
if (!joined.endsWith(fromExt)) continue;
|
|
2400
|
+
const stem = joined.slice(0, -fromExt.length);
|
|
2401
|
+
for (const toExt of toExts) {
|
|
2402
|
+
candidates.unshift(stem + toExt);
|
|
2403
|
+
}
|
|
2404
|
+
for (const indexSuffix of ["/index.ts", "/index.tsx", "/index.js", "/index.jsx"]) {
|
|
2405
|
+
candidates.unshift(stem + indexSuffix);
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
return candidates;
|
|
2409
|
+
}
|
|
2410
|
+
function resolveModuleImportPath(importerFilePath, moduleSpecifier, workspaceFiles) {
|
|
2411
|
+
const spec = moduleSpecifier.trim();
|
|
2412
|
+
if (!spec || !isRelativeModuleSpecifier(spec)) return null;
|
|
2413
|
+
const importerDir = path14.posix.dirname(normalizeWorkspacePath(importerFilePath));
|
|
2414
|
+
const joined = normalizeWorkspacePath(path14.posix.normalize(path14.posix.join(importerDir, spec)));
|
|
2415
|
+
return firstExistingPath(tsJsImportCandidates(joined), workspaceFiles);
|
|
2416
|
+
}
|
|
2417
|
+
function resolvePythonModulePath(importerFilePath, moduleSpecifier, workspaceFiles) {
|
|
2418
|
+
const moduleName = moduleSpecifier.trim().replace(/\s+/g, "");
|
|
2419
|
+
if (!moduleName) return null;
|
|
2420
|
+
const importerDir = path14.posix.dirname(normalizeWorkspacePath(importerFilePath));
|
|
2421
|
+
if (moduleName.startsWith(".")) {
|
|
2422
|
+
const dotMatch = /^(\.+)(.*)$/.exec(moduleName);
|
|
2423
|
+
const dotCount = dotMatch?.[1]?.length ?? 1;
|
|
2424
|
+
const rest = (dotMatch?.[2] ?? "").replace(/^\./, "");
|
|
2425
|
+
let baseDir = importerDir;
|
|
2426
|
+
for (let i = 1; i < dotCount; i++) {
|
|
2427
|
+
baseDir = path14.posix.dirname(baseDir);
|
|
2428
|
+
}
|
|
2429
|
+
const dottedPath2 = rest ? rest.split(".").join("/") : "";
|
|
2430
|
+
const relativeBase = dottedPath2 ? path14.posix.join(baseDir, dottedPath2) : baseDir;
|
|
2431
|
+
return firstExistingPath(
|
|
2432
|
+
[
|
|
2433
|
+
...withSuffixes(relativeBase, PYTHON_EXTENSIONS),
|
|
2434
|
+
...withSuffixes(path14.posix.join(relativeBase, "__init__"), [".py"])
|
|
2435
|
+
],
|
|
2436
|
+
workspaceFiles
|
|
2437
|
+
);
|
|
2438
|
+
}
|
|
2439
|
+
const dottedPath = moduleName.split(".").join("/");
|
|
2440
|
+
return firstExistingPath(
|
|
2441
|
+
[
|
|
2442
|
+
...withSuffixes(dottedPath, PYTHON_EXTENSIONS),
|
|
2443
|
+
...withSuffixes(path14.posix.join(importerDir, dottedPath), PYTHON_EXTENSIONS)
|
|
2444
|
+
],
|
|
2445
|
+
workspaceFiles
|
|
2446
|
+
);
|
|
2447
|
+
}
|
|
2448
|
+
function resolveIncludePath(importerFilePath, includePath, workspaceFiles) {
|
|
2449
|
+
const spec = includePath.trim().replace(/^["']|["']$/g, "");
|
|
2450
|
+
if (!spec) return null;
|
|
2451
|
+
const importerDir = path14.posix.dirname(normalizeWorkspacePath(importerFilePath));
|
|
2452
|
+
const joined = normalizeWorkspacePath(
|
|
2453
|
+
path14.posix.normalize(path14.posix.join(importerDir, spec.replace(/\\/g, "/")))
|
|
2454
|
+
);
|
|
2455
|
+
if (workspaceFiles.has(joined)) return joined;
|
|
2456
|
+
return firstExistingPath(withSuffixes(joined, C_CPP_EXTENSIONS), workspaceFiles);
|
|
2457
|
+
}
|
|
2458
|
+
function resolveJavaImportPath(moduleSpecifier, workspaceFiles) {
|
|
2459
|
+
const spec = moduleSpecifier.trim();
|
|
2460
|
+
if (!spec) return null;
|
|
2461
|
+
const pathLike = `${spec.replace(/\./g, "/")}.java`;
|
|
2462
|
+
if (workspaceFiles.has(pathLike)) return pathLike;
|
|
2463
|
+
for (const file of workspaceFiles) {
|
|
2464
|
+
if (file === pathLike || file.endsWith(`/${pathLike}`)) return file;
|
|
2465
|
+
}
|
|
2466
|
+
return null;
|
|
2467
|
+
}
|
|
2468
|
+
function resolveGoImportPath(importerFilePath, moduleSpecifier, workspaceFiles) {
|
|
2469
|
+
const spec = moduleSpecifier.trim();
|
|
2470
|
+
if (!spec) return null;
|
|
2471
|
+
if (isRelativeModuleSpecifier(spec)) {
|
|
2472
|
+
const importerDir = path14.posix.dirname(normalizeWorkspacePath(importerFilePath));
|
|
2473
|
+
const joined = normalizeWorkspacePath(path14.posix.normalize(path14.posix.join(importerDir, spec)));
|
|
2474
|
+
if (workspaceFiles.has(joined)) return joined;
|
|
2475
|
+
return firstExistingPath(withSuffixes(joined, [".go"]), workspaceFiles);
|
|
2476
|
+
}
|
|
2477
|
+
const leaf = spec.split("/").filter(Boolean).at(-1);
|
|
2478
|
+
if (!leaf) return null;
|
|
2479
|
+
for (const file of workspaceFiles) {
|
|
2480
|
+
if (file.endsWith(`/${leaf}.go`) || file === `${leaf}.go`) return file;
|
|
2481
|
+
}
|
|
2482
|
+
return null;
|
|
2483
|
+
}
|
|
2484
|
+
function resolveImportSourcePath(importerFilePath, moduleSpecifier, workspaceFiles) {
|
|
2485
|
+
const spec = moduleSpecifier.trim();
|
|
2486
|
+
if (!spec) return null;
|
|
2487
|
+
const tsResult = resolveModuleImportPath(importerFilePath, spec, workspaceFiles);
|
|
2488
|
+
if (tsResult) return tsResult;
|
|
2489
|
+
const languageKey = getLanguageKeyForFilePath(importerFilePath);
|
|
2490
|
+
switch (languageKey) {
|
|
2491
|
+
case "python":
|
|
2492
|
+
return resolvePythonModulePath(importerFilePath, spec, workspaceFiles);
|
|
2493
|
+
case "c":
|
|
2494
|
+
case "cpp":
|
|
2495
|
+
return resolveIncludePath(importerFilePath, spec, workspaceFiles);
|
|
2496
|
+
case "java":
|
|
2497
|
+
return resolveJavaImportPath(spec, workspaceFiles);
|
|
2498
|
+
case "go":
|
|
2499
|
+
return resolveGoImportPath(importerFilePath, spec, workspaceFiles);
|
|
2500
|
+
default:
|
|
2501
|
+
return null;
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
function isModulePathSpecifier(name) {
|
|
2505
|
+
return isRelativeModuleSpecifier(name.trim());
|
|
2506
|
+
}
|
|
2507
|
+
var TS_JS_EXTENSIONS, PYTHON_EXTENSIONS, C_CPP_EXTENSIONS;
|
|
2508
|
+
var init_resolve_module_import_path = __esm({
|
|
2509
|
+
"src/code-nav/resolve-module-import-path.ts"() {
|
|
2510
|
+
"use strict";
|
|
2511
|
+
init_language_registry();
|
|
2512
|
+
TS_JS_EXTENSIONS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js", "/index.jsx"];
|
|
2513
|
+
PYTHON_EXTENSIONS = [".py", "/__init__.py"];
|
|
2514
|
+
C_CPP_EXTENSIONS = ["", ".h", ".hpp", ".hh", ".hxx", ".c", ".cpp", ".cc", ".cxx"];
|
|
2515
|
+
}
|
|
2516
|
+
});
|
|
2517
|
+
|
|
2518
|
+
// src/code-nav/enrich-tag-module-paths.ts
|
|
2519
|
+
function enrichTagsWithModulePaths(tags, filePath, workspaceFiles) {
|
|
2520
|
+
return tags.map((tag) => {
|
|
2521
|
+
if (tag.kind !== "module" || tag.role !== "ref" || !isModulePathSpecifier(tag.name)) {
|
|
2522
|
+
return tag;
|
|
2523
|
+
}
|
|
2524
|
+
const resolved = resolveModuleImportPath(filePath, tag.name, workspaceFiles);
|
|
2525
|
+
if (!resolved) return tag;
|
|
2526
|
+
return { ...tag, navTargetPath: resolved };
|
|
2527
|
+
});
|
|
2528
|
+
}
|
|
2529
|
+
var init_enrich_tag_module_paths = __esm({
|
|
2530
|
+
"src/code-nav/enrich-tag-module-paths.ts"() {
|
|
2531
|
+
"use strict";
|
|
2532
|
+
init_resolve_module_import_path();
|
|
2533
|
+
}
|
|
2534
|
+
});
|
|
2535
|
+
|
|
2536
|
+
// src/code-nav/enrich-tag-module-paths-async.ts
|
|
2537
|
+
async function enrichTagsWithModulePathsAsync(tags, filePath, workspaceFiles, state) {
|
|
2538
|
+
const chunkSize = 64;
|
|
2539
|
+
const enriched = [];
|
|
2540
|
+
for (let i = 0; i < tags.length; i += chunkSize) {
|
|
2541
|
+
await yieldDuringCodeNavWork(state);
|
|
2542
|
+
const chunk = tags.slice(i, i + chunkSize);
|
|
2543
|
+
enriched.push(...enrichTagsWithModulePaths(chunk, filePath, workspaceFiles));
|
|
2544
|
+
}
|
|
2545
|
+
return enriched;
|
|
2546
|
+
}
|
|
2547
|
+
var init_enrich_tag_module_paths_async = __esm({
|
|
2548
|
+
"src/code-nav/enrich-tag-module-paths-async.ts"() {
|
|
2549
|
+
"use strict";
|
|
2550
|
+
init_yield_during_work();
|
|
2551
|
+
init_enrich_tag_module_paths();
|
|
2552
|
+
}
|
|
2553
|
+
});
|
|
2554
|
+
|
|
2555
|
+
// src/code-nav/augment-function-type-param-references.ts
|
|
2556
|
+
function tagDedupeKey(tag) {
|
|
2557
|
+
return `${tag.startLine}:${tag.startColumn}:${tag.endLine}:${tag.endColumn}:${tag.role}:${tag.kind}:${tag.name}`;
|
|
2558
|
+
}
|
|
2559
|
+
function collectParamNames(functionTypeNode) {
|
|
2560
|
+
const names = /* @__PURE__ */ new Set();
|
|
2561
|
+
const parameters = functionTypeNode.childForFieldName("parameters");
|
|
2562
|
+
if (!parameters) return names;
|
|
2563
|
+
function walk(node) {
|
|
2564
|
+
if (PARAM_NODE_TYPES.has(node.type)) {
|
|
2565
|
+
const nameNode = node.childForFieldName("pattern") ?? node.namedChildren.find((c) => c.type === "identifier");
|
|
2566
|
+
if (nameNode?.type === "identifier") names.add(nameNode.text);
|
|
2567
|
+
return;
|
|
2568
|
+
}
|
|
2569
|
+
for (const child of node.namedChildren) walk(child);
|
|
2570
|
+
}
|
|
2571
|
+
walk(parameters);
|
|
2572
|
+
return names;
|
|
2573
|
+
}
|
|
2574
|
+
function isDefinitionName(node) {
|
|
2575
|
+
const parent = node.parent;
|
|
2576
|
+
if (!parent) return false;
|
|
2577
|
+
if (PARAM_NODE_TYPES.has(parent.type)) return true;
|
|
2578
|
+
if (parent.type === "type_parameter" && parent.childForFieldName("name") === node) return true;
|
|
2579
|
+
return false;
|
|
2580
|
+
}
|
|
2581
|
+
function tagFromIdentifierNode(node) {
|
|
2582
|
+
return {
|
|
2583
|
+
name: node.text,
|
|
2584
|
+
role: "ref",
|
|
2585
|
+
kind: "variable",
|
|
2586
|
+
startLine: node.startPosition.row,
|
|
2587
|
+
startColumn: node.startPosition.column,
|
|
2588
|
+
endLine: node.endPosition.row,
|
|
2589
|
+
endColumn: node.endPosition.column
|
|
2590
|
+
};
|
|
2591
|
+
}
|
|
2592
|
+
function enclosingFunctionTypes(node) {
|
|
2593
|
+
const types = [];
|
|
2594
|
+
let current = node.parent;
|
|
2595
|
+
while (current) {
|
|
2596
|
+
if (current.type === "function_type") types.push(current);
|
|
2597
|
+
current = current.parent;
|
|
2598
|
+
}
|
|
2599
|
+
return types;
|
|
2600
|
+
}
|
|
2601
|
+
function isFunctionTypeParamReference(node) {
|
|
2602
|
+
if (node.type !== "identifier" || isDefinitionName(node)) return false;
|
|
2603
|
+
for (const functionType of enclosingFunctionTypes(node)) {
|
|
2604
|
+
const returnType = functionType.childForFieldName("return_type");
|
|
2605
|
+
if (!returnType?.descendantsOfType("identifier").some((desc) => desc.id === node.id)) continue;
|
|
2606
|
+
if (collectParamNames(functionType).has(node.text)) return true;
|
|
2607
|
+
}
|
|
2608
|
+
return false;
|
|
2609
|
+
}
|
|
2610
|
+
async function augmentFunctionTypeParamReferenceTags(tags, nameNodes, root) {
|
|
2611
|
+
const seen = new Set(tags.map(tagDedupeKey));
|
|
2612
|
+
const out = [...tags];
|
|
2613
|
+
const state = createCodeNavYieldState();
|
|
2614
|
+
async function walk(node) {
|
|
2615
|
+
if (isFunctionTypeParamReference(node)) {
|
|
2616
|
+
const tag = tagFromIdentifierNode(node);
|
|
2617
|
+
const key = tagDedupeKey(tag);
|
|
2618
|
+
if (!seen.has(key)) {
|
|
2619
|
+
seen.add(key);
|
|
2620
|
+
out.push(tag);
|
|
2621
|
+
nameNodes.set(`${tag.startLine}:${tag.startColumn}:${tag.name}:${tag.role}:${tag.kind}`, node);
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
for (const child of node.children) {
|
|
2625
|
+
await yieldDuringCodeNavWork(state);
|
|
2626
|
+
await walk(child);
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
await walk(root);
|
|
2630
|
+
return out;
|
|
2631
|
+
}
|
|
2632
|
+
var PARAM_NODE_TYPES;
|
|
2633
|
+
var init_augment_function_type_param_references = __esm({
|
|
2634
|
+
"src/code-nav/augment-function-type-param-references.ts"() {
|
|
2635
|
+
"use strict";
|
|
2636
|
+
init_yield_during_work();
|
|
2637
|
+
PARAM_NODE_TYPES = /* @__PURE__ */ new Set(["required_parameter", "optional_parameter"]);
|
|
2638
|
+
}
|
|
2639
|
+
});
|
|
2640
|
+
|
|
2641
|
+
// src/code-nav/augment-type-reference-tags.ts
|
|
2642
|
+
function tagDedupeKey2(tag) {
|
|
2643
|
+
return `${tag.startLine}:${tag.startColumn}:${tag.endLine}:${tag.endColumn}:${tag.role}:${tag.kind}:${tag.name}`;
|
|
2644
|
+
}
|
|
2645
|
+
function isTypeDefinitionName(node) {
|
|
2646
|
+
const parent = node.parent;
|
|
2647
|
+
if (!parent) return false;
|
|
2648
|
+
return TYPE_DEFINITION_CONTAINER_TYPES.has(parent.type) && parent.childForFieldName("name") === node;
|
|
2649
|
+
}
|
|
2650
|
+
function tagFromTypeIdentifierNode(node) {
|
|
2651
|
+
return {
|
|
2652
|
+
name: node.text,
|
|
2653
|
+
role: "ref",
|
|
2654
|
+
kind: "type",
|
|
2655
|
+
startLine: node.startPosition.row,
|
|
2656
|
+
startColumn: node.startPosition.column,
|
|
2657
|
+
endLine: node.endPosition.row,
|
|
2658
|
+
endColumn: node.endPosition.column
|
|
2659
|
+
};
|
|
2660
|
+
}
|
|
2661
|
+
async function augmentTypeReferenceTags(tags, nameNodes, root) {
|
|
2662
|
+
const seen = new Set(tags.map(tagDedupeKey2));
|
|
2663
|
+
const out = [...tags];
|
|
2664
|
+
const state = createCodeNavYieldState();
|
|
2665
|
+
async function walk(node) {
|
|
2666
|
+
if (node.type === "type_identifier" && !isTypeDefinitionName(node)) {
|
|
2667
|
+
const tag = tagFromTypeIdentifierNode(node);
|
|
2668
|
+
const key = tagDedupeKey2(tag);
|
|
2669
|
+
if (!seen.has(key)) {
|
|
2670
|
+
seen.add(key);
|
|
2671
|
+
out.push(tag);
|
|
2672
|
+
nameNodes.set(`${tag.startLine}:${tag.startColumn}:${tag.name}:${tag.role}:${tag.kind}`, node);
|
|
2673
|
+
}
|
|
2674
|
+
}
|
|
2675
|
+
for (const child of node.children) {
|
|
2676
|
+
await yieldDuringCodeNavWork(state);
|
|
2677
|
+
await walk(child);
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
await walk(root);
|
|
2681
|
+
return out;
|
|
2682
|
+
}
|
|
2683
|
+
var TYPE_DEFINITION_CONTAINER_TYPES;
|
|
2684
|
+
var init_augment_type_reference_tags = __esm({
|
|
2685
|
+
"src/code-nav/augment-type-reference-tags.ts"() {
|
|
2686
|
+
"use strict";
|
|
2687
|
+
init_yield_during_work();
|
|
2688
|
+
TYPE_DEFINITION_CONTAINER_TYPES = /* @__PURE__ */ new Set([
|
|
2689
|
+
"function_declaration",
|
|
2690
|
+
"function_signature",
|
|
2691
|
+
"generator_function_declaration",
|
|
2692
|
+
"class_declaration",
|
|
2693
|
+
"abstract_class_declaration",
|
|
2694
|
+
"interface_declaration",
|
|
2695
|
+
"type_alias_declaration",
|
|
2696
|
+
"enum_declaration",
|
|
2697
|
+
"module",
|
|
2698
|
+
"type_parameter",
|
|
2699
|
+
"method_definition",
|
|
2700
|
+
"method_signature",
|
|
2701
|
+
"abstract_method_signature",
|
|
2702
|
+
"property_signature",
|
|
2703
|
+
"public_field_definition"
|
|
2704
|
+
]);
|
|
2705
|
+
}
|
|
2706
|
+
});
|
|
2707
|
+
|
|
2708
|
+
// src/code-nav/scope-chain.ts
|
|
2709
|
+
function serializeScopeChain(chain2) {
|
|
2710
|
+
if (chain2.length === 0) return null;
|
|
2711
|
+
return chain2.map((anchor) => `${anchor.startLine}:${anchor.startColumn}`).join(",");
|
|
2712
|
+
}
|
|
2713
|
+
var init_scope_chain = __esm({
|
|
2714
|
+
"src/code-nav/scope-chain.ts"() {
|
|
2715
|
+
"use strict";
|
|
2716
|
+
}
|
|
2717
|
+
});
|
|
2718
|
+
|
|
2719
|
+
// src/code-nav/enrich-tag-scope.ts
|
|
2720
|
+
function scopeAnchorFromNode(node) {
|
|
2721
|
+
const nameNode = node.childForFieldName("name");
|
|
2722
|
+
if (nameNode) {
|
|
2723
|
+
return {
|
|
2724
|
+
startLine: nameNode.startPosition.row,
|
|
2725
|
+
startColumn: nameNode.startPosition.column
|
|
2726
|
+
};
|
|
2727
|
+
}
|
|
2728
|
+
return {
|
|
2729
|
+
startLine: node.startPosition.row,
|
|
2730
|
+
startColumn: node.startPosition.column
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
2733
|
+
function findEnclosingScopeChain(nameNode) {
|
|
2734
|
+
const chain2 = [];
|
|
2735
|
+
let current = nameNode.parent;
|
|
2736
|
+
while (current) {
|
|
2737
|
+
if (SCOPE_CONTAINER_TYPES.has(current.type)) {
|
|
2738
|
+
chain2.push(scopeAnchorFromNode(current));
|
|
2739
|
+
}
|
|
2740
|
+
current = current.parent;
|
|
2741
|
+
}
|
|
2742
|
+
return chain2;
|
|
2743
|
+
}
|
|
2744
|
+
function findEnclosingScopes(nameNode) {
|
|
2745
|
+
const scopeChain = findEnclosingScopeChain(nameNode);
|
|
2746
|
+
return {
|
|
2747
|
+
scope: scopeChain[0] ?? null,
|
|
2748
|
+
parentScope: scopeChain[1] ?? null,
|
|
2749
|
+
scopeChain
|
|
2750
|
+
};
|
|
2751
|
+
}
|
|
2752
|
+
async function enrichTagsWithEnclosingScope(tags, nameNodes) {
|
|
2753
|
+
const state = createCodeNavYieldState();
|
|
2754
|
+
const out = [];
|
|
2755
|
+
for (const tag of tags) {
|
|
2756
|
+
await yieldDuringCodeNavWork(state);
|
|
2757
|
+
const key = `${tag.startLine}:${tag.startColumn}:${tag.name}:${tag.role}:${tag.kind}`;
|
|
2758
|
+
const nameNode = nameNodes.get(key);
|
|
2759
|
+
if (!nameNode) {
|
|
2760
|
+
out.push(tag);
|
|
2761
|
+
continue;
|
|
2762
|
+
}
|
|
2763
|
+
const { scope, parentScope, scopeChain } = findEnclosingScopes(nameNode);
|
|
2764
|
+
if (!scope) {
|
|
2765
|
+
out.push(tag);
|
|
2766
|
+
continue;
|
|
2767
|
+
}
|
|
2768
|
+
out.push({
|
|
2769
|
+
...tag,
|
|
2770
|
+
scopeStartLine: scope.startLine,
|
|
2771
|
+
scopeStartColumn: scope.startColumn,
|
|
2772
|
+
parentScopeStartLine: parentScope?.startLine,
|
|
2773
|
+
parentScopeStartColumn: parentScope?.startColumn,
|
|
2774
|
+
scopeChain: serializeScopeChain(scopeChain) ?? void 0
|
|
2775
|
+
});
|
|
2776
|
+
}
|
|
2777
|
+
return out;
|
|
2778
|
+
}
|
|
2779
|
+
var SCOPE_CONTAINER_TYPES;
|
|
2780
|
+
var init_enrich_tag_scope = __esm({
|
|
2781
|
+
"src/code-nav/enrich-tag-scope.ts"() {
|
|
2782
|
+
"use strict";
|
|
2783
|
+
init_scope_chain();
|
|
2784
|
+
init_yield_during_work();
|
|
2785
|
+
SCOPE_CONTAINER_TYPES = /* @__PURE__ */ new Set([
|
|
2786
|
+
"function_declaration",
|
|
2787
|
+
"function_expression",
|
|
2788
|
+
"generator_function",
|
|
2789
|
+
"generator_function_declaration",
|
|
2790
|
+
"method_definition",
|
|
2791
|
+
"method_signature",
|
|
2792
|
+
"abstract_method_signature",
|
|
2793
|
+
"class_declaration",
|
|
2794
|
+
"abstract_class_declaration",
|
|
2795
|
+
"interface_declaration",
|
|
2796
|
+
"module",
|
|
2797
|
+
"arrow_function",
|
|
2798
|
+
"function_type",
|
|
2799
|
+
"function_item",
|
|
2800
|
+
"impl_item",
|
|
2801
|
+
"function_definition",
|
|
2802
|
+
"class_definition"
|
|
2803
|
+
]);
|
|
2804
|
+
}
|
|
2805
|
+
});
|
|
2806
|
+
|
|
2807
|
+
// src/code-nav/member-access/c.ts
|
|
2808
|
+
var C_MEMBER_ACCESS_RULES;
|
|
2809
|
+
var init_c = __esm({
|
|
2810
|
+
"src/code-nav/member-access/c.ts"() {
|
|
2811
|
+
"use strict";
|
|
2812
|
+
C_MEMBER_ACCESS_RULES = [
|
|
2813
|
+
{ parentType: "field_expression", objectField: "argument", propertyField: "field", tagKind: "member" }
|
|
2814
|
+
];
|
|
2815
|
+
}
|
|
2816
|
+
});
|
|
2817
|
+
|
|
2818
|
+
// src/code-nav/member-access/cpp.ts
|
|
2819
|
+
var CPP_MEMBER_ACCESS_RULES;
|
|
2820
|
+
var init_cpp = __esm({
|
|
2821
|
+
"src/code-nav/member-access/cpp.ts"() {
|
|
2822
|
+
"use strict";
|
|
2823
|
+
init_c();
|
|
2824
|
+
CPP_MEMBER_ACCESS_RULES = [
|
|
2825
|
+
...C_MEMBER_ACCESS_RULES,
|
|
2826
|
+
{ parentType: "qualified_identifier", objectField: "scope", propertyField: "name", tagKind: "member" }
|
|
2827
|
+
];
|
|
2828
|
+
}
|
|
2829
|
+
});
|
|
2830
|
+
|
|
2831
|
+
// src/code-nav/member-access/go.ts
|
|
2832
|
+
var GO_MEMBER_ACCESS_RULES;
|
|
2833
|
+
var init_go = __esm({
|
|
2834
|
+
"src/code-nav/member-access/go.ts"() {
|
|
2835
|
+
"use strict";
|
|
2836
|
+
GO_MEMBER_ACCESS_RULES = [
|
|
2837
|
+
{ parentType: "selector_expression", objectField: "operand", propertyField: "field", tagKind: "member" }
|
|
2838
|
+
];
|
|
2839
|
+
}
|
|
2840
|
+
});
|
|
2841
|
+
|
|
2842
|
+
// src/code-nav/member-access/javascript.ts
|
|
2843
|
+
var ECMA_SCRIPT_MEMBER_ACCESS_RULES, JAVASCRIPT_MEMBER_ACCESS_RULES;
|
|
2844
|
+
var init_javascript = __esm({
|
|
2845
|
+
"src/code-nav/member-access/javascript.ts"() {
|
|
2846
|
+
"use strict";
|
|
2847
|
+
ECMA_SCRIPT_MEMBER_ACCESS_RULES = [
|
|
2848
|
+
{ parentType: "member_expression", objectField: "object", propertyField: "property", tagKind: "member" }
|
|
2849
|
+
];
|
|
2850
|
+
JAVASCRIPT_MEMBER_ACCESS_RULES = ECMA_SCRIPT_MEMBER_ACCESS_RULES;
|
|
2851
|
+
}
|
|
2852
|
+
});
|
|
2853
|
+
|
|
2854
|
+
// src/code-nav/member-access/java.ts
|
|
2855
|
+
var JAVA_MEMBER_ACCESS_RULES;
|
|
2856
|
+
var init_java = __esm({
|
|
2857
|
+
"src/code-nav/member-access/java.ts"() {
|
|
2858
|
+
"use strict";
|
|
2859
|
+
JAVA_MEMBER_ACCESS_RULES = [
|
|
2860
|
+
{ parentType: "field_access", objectField: "object", propertyField: "field", tagKind: "member" },
|
|
2861
|
+
{ parentType: "method_invocation", objectField: "object", propertyField: "name", tagKind: "call" }
|
|
2862
|
+
];
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
|
|
2866
|
+
// src/code-nav/member-access/python.ts
|
|
2867
|
+
var PYTHON_MEMBER_ACCESS_RULES;
|
|
2868
|
+
var init_python = __esm({
|
|
2869
|
+
"src/code-nav/member-access/python.ts"() {
|
|
2870
|
+
"use strict";
|
|
2871
|
+
PYTHON_MEMBER_ACCESS_RULES = [
|
|
2872
|
+
{ parentType: "attribute", objectField: "object", propertyField: "attribute", tagKind: "member" }
|
|
2873
|
+
];
|
|
2874
|
+
}
|
|
2875
|
+
});
|
|
2876
|
+
|
|
2877
|
+
// src/code-nav/member-access/ruby.ts
|
|
2878
|
+
var RUBY_MEMBER_ACCESS_RULES;
|
|
2879
|
+
var init_ruby = __esm({
|
|
2880
|
+
"src/code-nav/member-access/ruby.ts"() {
|
|
2881
|
+
"use strict";
|
|
2882
|
+
RUBY_MEMBER_ACCESS_RULES = [
|
|
2883
|
+
{ parentType: "call", objectField: "receiver", propertyField: "method", tagKind: "call" }
|
|
2884
|
+
];
|
|
2885
|
+
}
|
|
2886
|
+
});
|
|
2887
|
+
|
|
2888
|
+
// src/code-nav/member-access/rust.ts
|
|
2889
|
+
var RUST_MEMBER_ACCESS_RULES;
|
|
2890
|
+
var init_rust = __esm({
|
|
2891
|
+
"src/code-nav/member-access/rust.ts"() {
|
|
2892
|
+
"use strict";
|
|
2893
|
+
RUST_MEMBER_ACCESS_RULES = [
|
|
2894
|
+
{ parentType: "field_expression", objectField: "value", propertyField: "field", tagKind: "member" },
|
|
2895
|
+
{ parentType: "scoped_identifier", objectField: "path", propertyField: "name", tagKind: "member" }
|
|
2896
|
+
];
|
|
2897
|
+
}
|
|
2898
|
+
});
|
|
2899
|
+
|
|
2900
|
+
// src/code-nav/member-access/tsx.ts
|
|
2901
|
+
var init_tsx = __esm({
|
|
2902
|
+
"src/code-nav/member-access/tsx.ts"() {
|
|
2903
|
+
"use strict";
|
|
2904
|
+
init_javascript();
|
|
2905
|
+
}
|
|
2906
|
+
});
|
|
2907
|
+
|
|
2908
|
+
// src/code-nav/member-access/typescript.ts
|
|
2909
|
+
var init_typescript = __esm({
|
|
2910
|
+
"src/code-nav/member-access/typescript.ts"() {
|
|
2911
|
+
"use strict";
|
|
2912
|
+
init_javascript();
|
|
2913
|
+
}
|
|
2914
|
+
});
|
|
2915
|
+
|
|
2916
|
+
// src/code-nav/member-access/registry.ts
|
|
2917
|
+
function memberAccessRulesForLanguageKey(languageKey) {
|
|
2918
|
+
if (!languageKey) return [];
|
|
2919
|
+
return MEMBER_ACCESS_RULES_BY_LANGUAGE_KEY[languageKey] ?? [];
|
|
2920
|
+
}
|
|
2921
|
+
var MEMBER_ACCESS_RULES_BY_LANGUAGE_KEY;
|
|
2922
|
+
var init_registry = __esm({
|
|
2923
|
+
"src/code-nav/member-access/registry.ts"() {
|
|
2924
|
+
"use strict";
|
|
2925
|
+
init_c();
|
|
2926
|
+
init_cpp();
|
|
2927
|
+
init_go();
|
|
2928
|
+
init_javascript();
|
|
2929
|
+
init_java();
|
|
2930
|
+
init_python();
|
|
2931
|
+
init_ruby();
|
|
2932
|
+
init_rust();
|
|
2933
|
+
init_tsx();
|
|
2934
|
+
init_typescript();
|
|
2935
|
+
MEMBER_ACCESS_RULES_BY_LANGUAGE_KEY = {
|
|
2936
|
+
javascript: JAVASCRIPT_MEMBER_ACCESS_RULES,
|
|
2937
|
+
typescript: ECMA_SCRIPT_MEMBER_ACCESS_RULES,
|
|
2938
|
+
tsx: ECMA_SCRIPT_MEMBER_ACCESS_RULES,
|
|
2939
|
+
python: PYTHON_MEMBER_ACCESS_RULES,
|
|
2940
|
+
go: GO_MEMBER_ACCESS_RULES,
|
|
2941
|
+
rust: RUST_MEMBER_ACCESS_RULES,
|
|
2942
|
+
ruby: RUBY_MEMBER_ACCESS_RULES,
|
|
2943
|
+
java: JAVA_MEMBER_ACCESS_RULES,
|
|
2944
|
+
c: C_MEMBER_ACCESS_RULES,
|
|
2945
|
+
cpp: CPP_MEMBER_ACCESS_RULES
|
|
2946
|
+
};
|
|
2947
|
+
}
|
|
2948
|
+
});
|
|
2949
|
+
|
|
2950
|
+
// src/code-nav/member-access/types.ts
|
|
2951
|
+
var MEMBER_NAME_NODE_TYPES;
|
|
2952
|
+
var init_types = __esm({
|
|
2953
|
+
"src/code-nav/member-access/types.ts"() {
|
|
2954
|
+
"use strict";
|
|
2955
|
+
MEMBER_NAME_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
2956
|
+
"identifier",
|
|
2957
|
+
"property_identifier",
|
|
2958
|
+
"field_identifier",
|
|
2959
|
+
"type_identifier",
|
|
2960
|
+
"constant",
|
|
2961
|
+
"package_identifier"
|
|
2962
|
+
]);
|
|
2963
|
+
}
|
|
2964
|
+
});
|
|
2965
|
+
|
|
2966
|
+
// src/code-nav/member-access/shared.ts
|
|
2967
|
+
function nodesMatch(a, b) {
|
|
2968
|
+
return a.startPosition.row === b.startPosition.row && a.startPosition.column === b.startPosition.column && a.text === b.text;
|
|
2969
|
+
}
|
|
2970
|
+
function fieldNodeMatches(node, candidate) {
|
|
2971
|
+
return node != null && nodesMatch(node, candidate);
|
|
2972
|
+
}
|
|
2973
|
+
function isReceiverNameNode(node) {
|
|
2974
|
+
return MEMBER_NAME_NODE_TYPES.has(node.type) || node.type === "this" || node.type === "self" || node.type === "super";
|
|
2975
|
+
}
|
|
2976
|
+
function objectNodeFromAccessNode(accessNode, rule) {
|
|
2977
|
+
const objectNode = accessNode.childForFieldName(rule.objectField);
|
|
2978
|
+
if (!objectNode || !isReceiverNameNode(objectNode)) return null;
|
|
2979
|
+
return objectNode;
|
|
2980
|
+
}
|
|
2981
|
+
function isMemberAccessPropertyNameNode(nameNode, rules) {
|
|
2982
|
+
const parent = nameNode.parent;
|
|
2983
|
+
if (!parent) return false;
|
|
2984
|
+
for (const rule of rules) {
|
|
2985
|
+
if (parent.type !== rule.parentType) continue;
|
|
2986
|
+
if (fieldNodeMatches(parent.childForFieldName(rule.propertyField), nameNode)) return true;
|
|
2987
|
+
}
|
|
2988
|
+
return false;
|
|
2989
|
+
}
|
|
2990
|
+
var init_shared = __esm({
|
|
2991
|
+
"src/code-nav/member-access/shared.ts"() {
|
|
2992
|
+
"use strict";
|
|
2993
|
+
init_types();
|
|
2994
|
+
}
|
|
2995
|
+
});
|
|
2996
|
+
|
|
2997
|
+
// src/code-nav/member-access/index.ts
|
|
2998
|
+
function tagDedupeKey3(tag) {
|
|
2999
|
+
return `${tag.startLine}:${tag.startColumn}:${tag.endLine}:${tag.endColumn}:${tag.role}:${tag.kind}:${tag.name}`;
|
|
3000
|
+
}
|
|
3001
|
+
function tagFromReceiverNode(node) {
|
|
3002
|
+
return {
|
|
3003
|
+
name: node.text,
|
|
3004
|
+
role: "ref",
|
|
3005
|
+
kind: "variable",
|
|
3006
|
+
startLine: node.startPosition.row,
|
|
3007
|
+
startColumn: node.startPosition.column,
|
|
3008
|
+
endLine: node.endPosition.row,
|
|
3009
|
+
endColumn: node.endPosition.column
|
|
3010
|
+
};
|
|
3011
|
+
}
|
|
3012
|
+
function lookupNameNode(nameNodes, tag) {
|
|
3013
|
+
const key = `${tag.startLine}:${tag.startColumn}:${tag.name}:${tag.role}:${tag.kind}`;
|
|
3014
|
+
if (nameNodes.has(key)) return nameNodes.get(key);
|
|
3015
|
+
for (const node of nameNodes.values()) {
|
|
3016
|
+
if (node.text === tag.name && node.startPosition.row === tag.startLine && node.startPosition.column === tag.startColumn) {
|
|
3017
|
+
return node;
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
return null;
|
|
3021
|
+
}
|
|
3022
|
+
function filterMemberAccessPropertyTags(tags, nameNodes, languageKey) {
|
|
3023
|
+
const rules = memberAccessRulesForLanguageKey(languageKey);
|
|
3024
|
+
if (rules.length === 0) return tags;
|
|
3025
|
+
return tags.filter((tag) => {
|
|
3026
|
+
if (tag.role !== "ref") return true;
|
|
3027
|
+
const nameNode = lookupNameNode(nameNodes, tag);
|
|
3028
|
+
if (!nameNode) return true;
|
|
3029
|
+
return !isMemberAccessPropertyNameNode(nameNode, rules);
|
|
3030
|
+
});
|
|
3031
|
+
}
|
|
3032
|
+
async function augmentMemberReceiverTags(tags, nameNodes, root, languageKey) {
|
|
3033
|
+
const rules = memberAccessRulesForLanguageKey(languageKey);
|
|
3034
|
+
if (rules.length === 0) return tags;
|
|
3035
|
+
const seen = new Set(tags.map(tagDedupeKey3));
|
|
3036
|
+
const seenRefPositions = new Set(
|
|
3037
|
+
tags.filter((tag) => tag.role === "ref").map((tag) => `${tag.startLine}:${tag.startColumn}:${tag.name}`)
|
|
3038
|
+
);
|
|
3039
|
+
const out = [...tags];
|
|
3040
|
+
const state = createCodeNavYieldState();
|
|
3041
|
+
for (const rule of rules) {
|
|
3042
|
+
for (const accessNode of root.descendantsOfType(rule.parentType)) {
|
|
3043
|
+
await yieldDuringCodeNavWork(state);
|
|
3044
|
+
const receiverNode = objectNodeFromAccessNode(accessNode, rule);
|
|
3045
|
+
if (!receiverNode) continue;
|
|
3046
|
+
const refPositionKey = `${receiverNode.startPosition.row}:${receiverNode.startPosition.column}:${receiverNode.text}`;
|
|
3047
|
+
if (seenRefPositions.has(refPositionKey)) continue;
|
|
3048
|
+
const tag = tagFromReceiverNode(receiverNode);
|
|
3049
|
+
const key = tagDedupeKey3(tag);
|
|
3050
|
+
if (seen.has(key)) continue;
|
|
3051
|
+
seen.add(key);
|
|
3052
|
+
seenRefPositions.add(refPositionKey);
|
|
3053
|
+
out.push(tag);
|
|
3054
|
+
nameNodes.set(`${tag.startLine}:${tag.startColumn}:${tag.name}:${tag.role}:${tag.kind}`, receiverNode);
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
return out;
|
|
3058
|
+
}
|
|
3059
|
+
var init_member_access = __esm({
|
|
3060
|
+
"src/code-nav/member-access/index.ts"() {
|
|
3061
|
+
"use strict";
|
|
3062
|
+
init_yield_during_work();
|
|
3063
|
+
init_registry();
|
|
3064
|
+
init_shared();
|
|
3065
|
+
}
|
|
3066
|
+
});
|
|
3067
|
+
|
|
3068
|
+
// src/code-nav/tree-sitter-assets-dir.ts
|
|
3069
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
3070
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
3071
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
3072
|
+
function repoNodeModulesDir(fromDir) {
|
|
3073
|
+
return join2(fromDir, "..", "..", "..", "node_modules");
|
|
3074
|
+
}
|
|
3075
|
+
function firstDirWithWebTreeSitterWasm(candidates) {
|
|
3076
|
+
for (const dir of candidates) {
|
|
3077
|
+
if (existsSync2(join2(dir, "web-tree-sitter.wasm"))) return dir;
|
|
3078
|
+
}
|
|
3079
|
+
return null;
|
|
3080
|
+
}
|
|
3081
|
+
function getTreeSitterAssetsDir() {
|
|
3082
|
+
const moduleDir = dirname2(fileURLToPath2(import.meta.url));
|
|
3083
|
+
const fromModule = firstDirWithWebTreeSitterWasm([
|
|
3084
|
+
join2(moduleDir, "tree-sitter"),
|
|
3085
|
+
join2(moduleDir, "..", "tree-sitter"),
|
|
3086
|
+
join2(moduleDir, "..", "..", "dist", "tree-sitter")
|
|
3087
|
+
]);
|
|
3088
|
+
if (fromModule) return fromModule;
|
|
3089
|
+
const fromNodeModules = firstDirWithWebTreeSitterWasm([join2(repoNodeModulesDir(moduleDir), "web-tree-sitter")]);
|
|
3090
|
+
if (fromNodeModules) return fromNodeModules;
|
|
3091
|
+
throw new Error(
|
|
3092
|
+
"Missing web-tree-sitter.wasm. Run `pnpm build` in packages/cli to copy tree-sitter assets into dist/tree-sitter."
|
|
3093
|
+
);
|
|
3094
|
+
}
|
|
3095
|
+
var init_tree_sitter_assets_dir = __esm({
|
|
3096
|
+
"src/code-nav/tree-sitter-assets-dir.ts"() {
|
|
3097
|
+
"use strict";
|
|
3098
|
+
}
|
|
3099
|
+
});
|
|
3100
|
+
|
|
3101
|
+
// src/code-nav/parser/tree-sitter-runtime.ts
|
|
3102
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
3103
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
3104
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
3105
|
+
import { Parser, Language, Query, LANGUAGE_VERSION, MIN_COMPATIBLE_VERSION } from "web-tree-sitter";
|
|
3106
|
+
function withTreeSitterRuntimeLock(fn) {
|
|
3107
|
+
const next = runtimeChain.then(() => Promise.resolve(fn()));
|
|
3108
|
+
runtimeChain = next.then(
|
|
3109
|
+
() => void 0,
|
|
3110
|
+
() => void 0
|
|
3111
|
+
);
|
|
3112
|
+
return next;
|
|
3113
|
+
}
|
|
3114
|
+
async function ensureParserInit() {
|
|
3115
|
+
if (!initPromise) {
|
|
3116
|
+
const assetsDir = getTreeSitterAssetsDir();
|
|
3117
|
+
initPromise = Parser.init({
|
|
3118
|
+
locateFile: (scriptName) => join3(assetsDir, scriptName)
|
|
3119
|
+
}).catch((e) => {
|
|
3120
|
+
initPromise = null;
|
|
3121
|
+
throw e;
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
await initPromise;
|
|
3125
|
+
}
|
|
3126
|
+
function resolveWasmPath(assetsDir, wasmFile) {
|
|
3127
|
+
const candidates = [
|
|
3128
|
+
join3(assetsDir, wasmFile),
|
|
3129
|
+
join3(assetsDir, "..", "..", "dist", "tree-sitter", wasmFile),
|
|
3130
|
+
join3(assetsDir, "..", "..", "..", "node_modules", wasmFile.replace(".wasm", ""), wasmFile)
|
|
3131
|
+
];
|
|
3132
|
+
const hit = candidates.find((p) => existsSync3(p));
|
|
3133
|
+
if (!hit) throw new Error(`Missing tree-sitter wasm: ${wasmFile}`);
|
|
3134
|
+
return hit;
|
|
3135
|
+
}
|
|
3136
|
+
function resolveTagsPath(assetsDir, tagsQueryFile) {
|
|
3137
|
+
const pkgName = tagsQueryFile.split("/")[0] ?? "";
|
|
3138
|
+
const candidates = [
|
|
3139
|
+
join3(CODE_NAV_QUERIES_ROOT, tagsQueryFile),
|
|
3140
|
+
join3(assetsDir, tagsQueryFile),
|
|
3141
|
+
join3(assetsDir, "..", "..", "dist", "tree-sitter", tagsQueryFile),
|
|
3142
|
+
join3(assetsDir, "..", "..", "..", "node_modules", pkgName, "queries", "tags.scm")
|
|
3143
|
+
];
|
|
3144
|
+
const hit = candidates.find((p) => existsSync3(p));
|
|
3145
|
+
if (!hit) throw new Error(`Missing tags query: ${tagsQueryFile}`);
|
|
3146
|
+
return hit;
|
|
3147
|
+
}
|
|
3148
|
+
async function loadLanguage(languageKey) {
|
|
3149
|
+
const spec = getLanguageSpec(languageKey);
|
|
3150
|
+
if (!spec) return null;
|
|
3151
|
+
if (failedLanguageKeys.has(languageKey)) return null;
|
|
3152
|
+
const cached = loadedByKey.get(languageKey);
|
|
3153
|
+
if (cached) return cached;
|
|
3154
|
+
await ensureParserInit();
|
|
3155
|
+
const assetsDir = getTreeSitterAssetsDir();
|
|
3156
|
+
const language = await Language.load(resolveWasmPath(assetsDir, spec.wasmFile));
|
|
3157
|
+
const abiVersion = language.abiVersion;
|
|
3158
|
+
if (abiVersion < MIN_COMPATIBLE_VERSION || abiVersion > LANGUAGE_VERSION) {
|
|
3159
|
+
failedLanguageKeys.add(languageKey);
|
|
3160
|
+
throw new Error(
|
|
3161
|
+
`Incompatible tree-sitter ABI for ${languageKey}: grammar=${abiVersion}, runtime=${MIN_COMPATIBLE_VERSION}-${LANGUAGE_VERSION}`
|
|
3162
|
+
);
|
|
3163
|
+
}
|
|
3164
|
+
const tagsSource = readFileSync2(resolveTagsPath(assetsDir, spec.tagsQueryFile), "utf8");
|
|
3165
|
+
const query = new Query(language, tagsSource);
|
|
3166
|
+
const loaded = { language, query };
|
|
3167
|
+
loadedByKey.set(languageKey, loaded);
|
|
3168
|
+
return loaded;
|
|
3169
|
+
}
|
|
3170
|
+
var initPromise, loadedByKey, failedLanguageKeys, runtimeChain, CODE_NAV_QUERIES_ROOT;
|
|
3171
|
+
var init_tree_sitter_runtime = __esm({
|
|
3172
|
+
"src/code-nav/parser/tree-sitter-runtime.ts"() {
|
|
3173
|
+
"use strict";
|
|
3174
|
+
init_tree_sitter_assets_dir();
|
|
3175
|
+
init_language_registry();
|
|
3176
|
+
initPromise = null;
|
|
3177
|
+
loadedByKey = /* @__PURE__ */ new Map();
|
|
3178
|
+
failedLanguageKeys = /* @__PURE__ */ new Set();
|
|
3179
|
+
runtimeChain = Promise.resolve();
|
|
3180
|
+
CODE_NAV_QUERIES_ROOT = join3(dirname3(fileURLToPath3(import.meta.url)), "..", "queries");
|
|
3181
|
+
}
|
|
3182
|
+
});
|
|
3183
|
+
|
|
3184
|
+
// src/code-nav/parser/parse-source-root.ts
|
|
3185
|
+
import { Parser as Parser2 } from "web-tree-sitter";
|
|
3186
|
+
async function parseSourceRoot(filePath, source) {
|
|
3187
|
+
const languageKey = getLanguageKeyForFilePath(filePath);
|
|
3188
|
+
if (!languageKey) return null;
|
|
3189
|
+
return withTreeSitterRuntimeLock(async () => {
|
|
3190
|
+
await yieldForBridgeInteractivePriority();
|
|
3191
|
+
let loaded;
|
|
3192
|
+
try {
|
|
3193
|
+
loaded = await loadLanguage(languageKey);
|
|
3194
|
+
} catch {
|
|
3195
|
+
return null;
|
|
3196
|
+
}
|
|
3197
|
+
if (!loaded) return null;
|
|
3198
|
+
const parser = new Parser2();
|
|
3199
|
+
parser.setLanguage(loaded.language);
|
|
3200
|
+
let tree = null;
|
|
3201
|
+
try {
|
|
3202
|
+
await yieldForBridgeInteractivePriority();
|
|
3203
|
+
assertBackgroundIndexingAllowed();
|
|
3204
|
+
tree = parser.parse(source);
|
|
3205
|
+
assertBackgroundIndexingAllowed();
|
|
3206
|
+
await yieldForBridgeInteractivePriority();
|
|
3207
|
+
if (!tree) return null;
|
|
3208
|
+
return {
|
|
3209
|
+
root: tree.rootNode,
|
|
3210
|
+
loaded,
|
|
3211
|
+
cleanup: () => {
|
|
3212
|
+
tree?.delete();
|
|
3213
|
+
parser.delete();
|
|
3214
|
+
}
|
|
3215
|
+
};
|
|
3216
|
+
} catch (err) {
|
|
3217
|
+
tree?.delete();
|
|
3218
|
+
parser.delete();
|
|
3219
|
+
if (isSymbolIndexDeferredError(err)) throw err;
|
|
3220
|
+
return null;
|
|
3221
|
+
}
|
|
3222
|
+
});
|
|
3223
|
+
}
|
|
3224
|
+
var init_parse_source_root = __esm({
|
|
3225
|
+
"src/code-nav/parser/parse-source-root.ts"() {
|
|
3226
|
+
"use strict";
|
|
3227
|
+
init_file_browser_in_flight();
|
|
3228
|
+
init_deferred_indexing();
|
|
3229
|
+
init_language_registry();
|
|
3230
|
+
init_tree_sitter_runtime();
|
|
3231
|
+
}
|
|
3232
|
+
});
|
|
3233
|
+
|
|
3234
|
+
// src/code-nav/parser/run-tags-query.ts
|
|
3235
|
+
async function runTagsQuery(loaded, root) {
|
|
3236
|
+
await yieldForBridgeInteractivePriority();
|
|
3237
|
+
assertBackgroundIndexingAllowed();
|
|
3238
|
+
const matches = loaded.query.matches(root);
|
|
3239
|
+
assertBackgroundIndexingAllowed();
|
|
3240
|
+
await yieldForBridgeInteractivePriority();
|
|
3241
|
+
return matches;
|
|
3242
|
+
}
|
|
3243
|
+
var init_run_tags_query = __esm({
|
|
3244
|
+
"src/code-nav/parser/run-tags-query.ts"() {
|
|
3245
|
+
"use strict";
|
|
3246
|
+
init_file_browser_in_flight();
|
|
3247
|
+
}
|
|
3248
|
+
});
|
|
3249
|
+
|
|
3250
|
+
// src/code-nav/parser/tags-from-matches.ts
|
|
3251
|
+
function parseCaptureRole(captureName) {
|
|
3252
|
+
if (captureName === "name") return null;
|
|
3253
|
+
const dot = captureName.indexOf(".");
|
|
3254
|
+
if (dot < 0) return null;
|
|
3255
|
+
const prefix = captureName.slice(0, dot);
|
|
3256
|
+
const kind = captureName.slice(dot + 1);
|
|
3257
|
+
if (prefix === "definition") return { role: "def", kind };
|
|
3258
|
+
if (prefix === "reference") return { role: "ref", kind };
|
|
3259
|
+
return null;
|
|
3260
|
+
}
|
|
3261
|
+
function tagDedupeKey4(tag) {
|
|
3262
|
+
return `${tag.startLine}:${tag.startColumn}:${tag.endLine}:${tag.endColumn}:${tag.role}:${tag.kind}:${tag.name}`;
|
|
3263
|
+
}
|
|
3264
|
+
function tagsFromMatches(matches) {
|
|
3265
|
+
const tags = [];
|
|
3266
|
+
const nameNodes = /* @__PURE__ */ new Map();
|
|
3267
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3268
|
+
for (const match of matches) {
|
|
3269
|
+
let name = null;
|
|
3270
|
+
let nameNode = null;
|
|
3271
|
+
const roleNodes = [];
|
|
3272
|
+
for (const capture of match.captures) {
|
|
3273
|
+
if (capture.name === "name") {
|
|
3274
|
+
name = capture.node.text;
|
|
3275
|
+
nameNode = capture.node;
|
|
3276
|
+
continue;
|
|
3277
|
+
}
|
|
3278
|
+
const parsed = parseCaptureRole(capture.name);
|
|
3279
|
+
if (parsed) roleNodes.push({ ...parsed, node: capture.node });
|
|
3280
|
+
}
|
|
3281
|
+
if (!name || !nameNode || roleNodes.length === 0) continue;
|
|
3282
|
+
for (const roleNode of roleNodes) {
|
|
3283
|
+
const tag = {
|
|
3284
|
+
name,
|
|
3285
|
+
role: roleNode.role,
|
|
3286
|
+
kind: roleNode.kind,
|
|
3287
|
+
startLine: nameNode.startPosition.row,
|
|
3288
|
+
startColumn: nameNode.startPosition.column,
|
|
3289
|
+
endLine: nameNode.endPosition.row,
|
|
3290
|
+
endColumn: nameNode.endPosition.column
|
|
3291
|
+
};
|
|
3292
|
+
const key = tagDedupeKey4(tag);
|
|
3293
|
+
if (seen.has(key)) continue;
|
|
3294
|
+
seen.add(key);
|
|
3295
|
+
tags.push(tag);
|
|
3296
|
+
nameNodes.set(`${tag.startLine}:${tag.startColumn}:${tag.name}:${tag.role}:${tag.kind}`, nameNode);
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
return { tags, nameNodes };
|
|
3300
|
+
}
|
|
3301
|
+
var init_tags_from_matches = __esm({
|
|
3302
|
+
"src/code-nav/parser/tags-from-matches.ts"() {
|
|
3303
|
+
"use strict";
|
|
3304
|
+
}
|
|
3305
|
+
});
|
|
3306
|
+
|
|
3307
|
+
// src/code-nav/parser/tags-from-matches-async.ts
|
|
3308
|
+
function tagDedupeKey5(tag) {
|
|
3309
|
+
return `${tag.startLine}:${tag.startColumn}:${tag.endLine}:${tag.endColumn}:${tag.role}:${tag.kind}:${tag.name}`;
|
|
3310
|
+
}
|
|
3311
|
+
async function tagsFromMatchesAsync(matches, state) {
|
|
3312
|
+
const tags = [];
|
|
3313
|
+
const nameNodes = /* @__PURE__ */ new Map();
|
|
3314
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3315
|
+
for (const match of matches) {
|
|
3316
|
+
await yieldDuringCodeNavWork(state);
|
|
3317
|
+
const partial = tagsFromMatches([match]);
|
|
3318
|
+
for (const tag of partial.tags) {
|
|
3319
|
+
const key = tagDedupeKey5(tag);
|
|
3320
|
+
if (seen.has(key)) continue;
|
|
3321
|
+
seen.add(key);
|
|
3322
|
+
tags.push(tag);
|
|
3323
|
+
}
|
|
3324
|
+
for (const [key, node] of partial.nameNodes) nameNodes.set(key, node);
|
|
3325
|
+
}
|
|
3326
|
+
return { tags, nameNodes };
|
|
3327
|
+
}
|
|
3328
|
+
var init_tags_from_matches_async = __esm({
|
|
3329
|
+
"src/code-nav/parser/tags-from-matches-async.ts"() {
|
|
3330
|
+
"use strict";
|
|
3331
|
+
init_yield_during_work();
|
|
3332
|
+
init_tags_from_matches();
|
|
3333
|
+
}
|
|
3334
|
+
});
|
|
3335
|
+
|
|
3336
|
+
// src/code-nav/parser/extract-tags.ts
|
|
3337
|
+
async function extractTagsFromSource(filePath, source) {
|
|
3338
|
+
const languageKey = getLanguageKeyForFilePath(filePath);
|
|
3339
|
+
await yieldForBridgeInteractivePriority();
|
|
3340
|
+
const parsed = await parseSourceRoot(filePath, source);
|
|
3341
|
+
if (!parsed) return [];
|
|
3342
|
+
try {
|
|
3343
|
+
const yieldState = createCodeNavYieldState();
|
|
3344
|
+
const matches = await runTagsQuery(parsed.loaded, parsed.root);
|
|
3345
|
+
const { tags, nameNodes } = await tagsFromMatchesAsync(matches, yieldState);
|
|
3346
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
3347
|
+
const filtered = filterMemberAccessPropertyTags(tags, nameNodes, languageKey);
|
|
3348
|
+
const withTypes = await augmentTypeReferenceTags(filtered, nameNodes, parsed.root);
|
|
3349
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
3350
|
+
const withFunctionTypeParamRefs = await augmentFunctionTypeParamReferenceTags(withTypes, nameNodes, parsed.root);
|
|
3351
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
3352
|
+
const withReceivers = await augmentMemberReceiverTags(withFunctionTypeParamRefs, nameNodes, parsed.root, languageKey);
|
|
3353
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
3354
|
+
return await enrichTagsWithEnclosingScope(withReceivers, nameNodes);
|
|
3355
|
+
} catch (err) {
|
|
3356
|
+
if (isSymbolIndexDeferredError(err)) throw err;
|
|
3357
|
+
return [];
|
|
3358
|
+
} finally {
|
|
3359
|
+
parsed.cleanup();
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
var init_extract_tags = __esm({
|
|
3363
|
+
"src/code-nav/parser/extract-tags.ts"() {
|
|
3364
|
+
"use strict";
|
|
3365
|
+
init_language_registry();
|
|
3366
|
+
init_augment_function_type_param_references();
|
|
3367
|
+
init_augment_type_reference_tags();
|
|
3368
|
+
init_enrich_tag_scope();
|
|
3369
|
+
init_member_access();
|
|
3370
|
+
init_yield_during_work();
|
|
3371
|
+
init_file_browser_in_flight();
|
|
3372
|
+
init_deferred_indexing();
|
|
3373
|
+
init_parse_source_root();
|
|
3374
|
+
init_run_tags_query();
|
|
3375
|
+
init_tags_from_matches_async();
|
|
3376
|
+
}
|
|
3377
|
+
});
|
|
3378
|
+
|
|
3379
|
+
// src/code-nav/parser-runtime.ts
|
|
3380
|
+
var init_parser_runtime = __esm({
|
|
3381
|
+
"src/code-nav/parser-runtime.ts"() {
|
|
3382
|
+
"use strict";
|
|
3383
|
+
init_extract_tags();
|
|
3384
|
+
init_parse_source_root();
|
|
3385
|
+
}
|
|
3386
|
+
});
|
|
3387
|
+
|
|
3388
|
+
// src/code-nav/symbol-index/imports/shared.ts
|
|
3389
|
+
function pushBinding(out, filePath, workspaceFiles, moduleSpecifier, localName, sourceName, importKind, nameNode) {
|
|
3390
|
+
if (!localName) return;
|
|
3391
|
+
out.push({
|
|
3392
|
+
localName,
|
|
3393
|
+
sourceName,
|
|
3394
|
+
moduleSpecifier,
|
|
3395
|
+
sourceFilePath: resolveImportSourcePath(filePath, moduleSpecifier, workspaceFiles),
|
|
3396
|
+
importKind,
|
|
3397
|
+
startLine: nameNode.startPosition.row,
|
|
3398
|
+
startColumn: nameNode.startPosition.column
|
|
3399
|
+
});
|
|
3400
|
+
}
|
|
3401
|
+
function stripQuotes(text) {
|
|
3402
|
+
const trimmed = text.trim();
|
|
3403
|
+
if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
|
|
3404
|
+
return trimmed.slice(1, -1);
|
|
3405
|
+
}
|
|
3406
|
+
return trimmed;
|
|
3407
|
+
}
|
|
3408
|
+
function stringLiteralText(node) {
|
|
3409
|
+
const fragment = node.descendantsOfType("string_fragment")[0];
|
|
3410
|
+
return stripQuotes(fragment?.text ?? node.text);
|
|
3411
|
+
}
|
|
3412
|
+
var init_shared2 = __esm({
|
|
3413
|
+
"src/code-nav/symbol-index/imports/shared.ts"() {
|
|
3414
|
+
"use strict";
|
|
3415
|
+
init_resolve_module_import_path();
|
|
3416
|
+
}
|
|
3417
|
+
});
|
|
3418
|
+
|
|
3419
|
+
// src/code-nav/symbol-index/imports/c.ts
|
|
3420
|
+
function extractCIncludeBindings(root, filePath, workspaceFiles) {
|
|
3421
|
+
const out = [];
|
|
3422
|
+
for (const node of root.descendantsOfType("preproc_include")) {
|
|
3423
|
+
const pathNode = node.childForFieldName("path");
|
|
3424
|
+
if (!pathNode) continue;
|
|
3425
|
+
const includePath = stringLiteralText(pathNode);
|
|
3426
|
+
const localName = includePath.split("/").filter(Boolean).at(-1)?.replace(/\.(h|hpp)$/, "") ?? includePath;
|
|
3427
|
+
pushBinding(out, filePath, workspaceFiles, includePath, localName, localName, "default", pathNode);
|
|
3428
|
+
}
|
|
3429
|
+
return out;
|
|
3430
|
+
}
|
|
3431
|
+
var init_c2 = __esm({
|
|
3432
|
+
"src/code-nav/symbol-index/imports/c.ts"() {
|
|
3433
|
+
"use strict";
|
|
3434
|
+
init_shared2();
|
|
3435
|
+
}
|
|
3436
|
+
});
|
|
3437
|
+
|
|
3438
|
+
// src/code-nav/symbol-index/imports/cpp.ts
|
|
3439
|
+
function extractCppImportBindings(root, filePath, workspaceFiles) {
|
|
3440
|
+
return extractCIncludeBindings(root, filePath, workspaceFiles);
|
|
3441
|
+
}
|
|
3442
|
+
var init_cpp2 = __esm({
|
|
3443
|
+
"src/code-nav/symbol-index/imports/cpp.ts"() {
|
|
3444
|
+
"use strict";
|
|
3445
|
+
init_c2();
|
|
3446
|
+
}
|
|
3447
|
+
});
|
|
3448
|
+
|
|
3449
|
+
// src/code-nav/symbol-index/imports/ecma-script-imports.ts
|
|
3450
|
+
function importKindForSpecifier(specifier, statementKind) {
|
|
3451
|
+
if (specifier.children.some((child) => child.type === "type")) return "type";
|
|
3452
|
+
return statementKind;
|
|
3453
|
+
}
|
|
3454
|
+
function collectFromImportSpecifier(out, filePath, workspaceFiles, moduleSpecifier, importKind, specifier) {
|
|
3455
|
+
const nameNode = specifier.childForFieldName("name");
|
|
3456
|
+
const aliasNode = specifier.childForFieldName("alias");
|
|
3457
|
+
if (!nameNode) return;
|
|
3458
|
+
const sourceName = nameNode.text;
|
|
3459
|
+
const localName = aliasNode?.text ?? sourceName;
|
|
3460
|
+
const effectiveKind = importKindForSpecifier(specifier, importKind);
|
|
3461
|
+
pushBinding(out, filePath, workspaceFiles, moduleSpecifier, localName, sourceName, effectiveKind, aliasNode ?? nameNode);
|
|
3462
|
+
}
|
|
3463
|
+
function collectFromImportClause(out, filePath, workspaceFiles, moduleSpecifier, importKind, clause) {
|
|
3464
|
+
const defaultName = clause.childForFieldName("name");
|
|
3465
|
+
if (defaultName) {
|
|
3466
|
+
pushBinding(out, filePath, workspaceFiles, moduleSpecifier, defaultName.text, defaultName.text, "default", defaultName);
|
|
3467
|
+
}
|
|
3468
|
+
for (const child of clause.children) {
|
|
3469
|
+
if (child.type === "named_imports") {
|
|
3470
|
+
for (const spec of child.children) {
|
|
3471
|
+
if (spec.type === "import_specifier") {
|
|
3472
|
+
collectFromImportSpecifier(out, filePath, workspaceFiles, moduleSpecifier, importKind, spec);
|
|
3473
|
+
}
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
if (child.type === "import_specifier") {
|
|
3477
|
+
collectFromImportSpecifier(out, filePath, workspaceFiles, moduleSpecifier, importKind, child);
|
|
3478
|
+
}
|
|
3479
|
+
if (child.type === "namespace_import") {
|
|
3480
|
+
const alias = child.childForFieldName("name") ?? child.namedChildren.find((n) => n.type === "identifier");
|
|
3481
|
+
if (alias) {
|
|
3482
|
+
pushBinding(out, filePath, workspaceFiles, moduleSpecifier, alias.text, alias.text, "namespace", alias);
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
function moduleSpecifierFromImport(node) {
|
|
3488
|
+
const source = node.childForFieldName("source");
|
|
3489
|
+
if (!source) return null;
|
|
3490
|
+
return stringLiteralText(source);
|
|
3491
|
+
}
|
|
3492
|
+
function collectFromImportStatement(out, filePath, workspaceFiles, node) {
|
|
3493
|
+
const moduleSpecifier = moduleSpecifierFromImport(node);
|
|
3494
|
+
if (!moduleSpecifier) return;
|
|
3495
|
+
const isTypeImport = node.children.some((child) => child.type === "type");
|
|
3496
|
+
const importKind = isTypeImport ? "type" : "named";
|
|
3497
|
+
const clause = node.children.find((child) => child.type === "import_clause");
|
|
3498
|
+
if (clause) {
|
|
3499
|
+
collectFromImportClause(out, filePath, workspaceFiles, moduleSpecifier, importKind, clause);
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
function extractEcmaScriptImportBindings(root, filePath, workspaceFiles) {
|
|
3503
|
+
const out = [];
|
|
3504
|
+
for (const node of root.descendantsOfType("import_statement")) {
|
|
3505
|
+
collectFromImportStatement(out, filePath, workspaceFiles, node);
|
|
3506
|
+
}
|
|
3507
|
+
return out;
|
|
3508
|
+
}
|
|
3509
|
+
var init_ecma_script_imports = __esm({
|
|
3510
|
+
"src/code-nav/symbol-index/imports/ecma-script-imports.ts"() {
|
|
3511
|
+
"use strict";
|
|
3512
|
+
init_shared2();
|
|
3513
|
+
}
|
|
3514
|
+
});
|
|
3515
|
+
|
|
3516
|
+
// src/code-nav/symbol-index/imports/ecma-script-exports.ts
|
|
3517
|
+
function exportKindForSpecifier(specifier, statementKind) {
|
|
3518
|
+
if (specifier.children.some((child) => child.type === "type")) return "type";
|
|
3519
|
+
return statementKind;
|
|
3520
|
+
}
|
|
3521
|
+
function collectFromExportSpecifier(out, filePath, workspaceFiles, moduleSpecifier, exportKind, specifier) {
|
|
3522
|
+
const nameNode = specifier.childForFieldName("name");
|
|
3523
|
+
const aliasNode = specifier.childForFieldName("alias");
|
|
3524
|
+
if (!nameNode) return;
|
|
3525
|
+
const sourceName = nameNode.text;
|
|
3526
|
+
const localName = aliasNode?.text ?? sourceName;
|
|
3527
|
+
const effectiveKind = exportKindForSpecifier(specifier, exportKind);
|
|
3528
|
+
pushBinding(out, filePath, workspaceFiles, moduleSpecifier, localName, sourceName, effectiveKind, aliasNode ?? nameNode);
|
|
3529
|
+
}
|
|
3530
|
+
function moduleSpecifierFromExport(node) {
|
|
3531
|
+
const source = node.childForFieldName("source");
|
|
3532
|
+
if (!source) return null;
|
|
3533
|
+
return stringLiteralText(source);
|
|
3534
|
+
}
|
|
3535
|
+
function isStarReexport(node) {
|
|
3536
|
+
if (!moduleSpecifierFromExport(node)) return false;
|
|
3537
|
+
if (node.descendantsOfType("export_specifier").length > 0) return false;
|
|
3538
|
+
if (node.descendantsOfType("namespace_export").length > 0) return false;
|
|
3539
|
+
if (node.childForFieldName("declaration")) return false;
|
|
3540
|
+
return node.text.includes("*");
|
|
3541
|
+
}
|
|
3542
|
+
function extractEcmaScriptReexportBindings(root, filePath, workspaceFiles) {
|
|
3543
|
+
const out = [];
|
|
3544
|
+
for (const node of root.descendantsOfType("export_statement")) {
|
|
3545
|
+
const moduleSpecifier = moduleSpecifierFromExport(node);
|
|
3546
|
+
if (!moduleSpecifier) continue;
|
|
3547
|
+
const isTypeExport = node.children.some((child) => child.type === "type");
|
|
3548
|
+
const exportKind = isTypeExport ? "type" : "reexport";
|
|
3549
|
+
if (isStarReexport(node)) {
|
|
3550
|
+
const anchor = node.childForFieldName("source") ?? node;
|
|
3551
|
+
pushBinding(out, filePath, workspaceFiles, moduleSpecifier, "*", "*", "star", anchor);
|
|
3552
|
+
continue;
|
|
3553
|
+
}
|
|
3554
|
+
for (const spec of node.descendantsOfType("export_specifier")) {
|
|
3555
|
+
collectFromExportSpecifier(out, filePath, workspaceFiles, moduleSpecifier, exportKind, spec);
|
|
3556
|
+
}
|
|
3557
|
+
for (const ns of node.descendantsOfType("namespace_export")) {
|
|
3558
|
+
const alias = ns.childForFieldName("name") ?? ns.namedChildren.find((n) => n.type === "identifier");
|
|
3559
|
+
if (alias) {
|
|
3560
|
+
pushBinding(out, filePath, workspaceFiles, moduleSpecifier, alias.text, alias.text, "namespace", alias);
|
|
3561
|
+
}
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
return out;
|
|
3565
|
+
}
|
|
3566
|
+
var init_ecma_script_exports = __esm({
|
|
3567
|
+
"src/code-nav/symbol-index/imports/ecma-script-exports.ts"() {
|
|
3568
|
+
"use strict";
|
|
3569
|
+
init_shared2();
|
|
3570
|
+
}
|
|
3571
|
+
});
|
|
3572
|
+
|
|
3573
|
+
// src/code-nav/symbol-index/imports/ecma-script.ts
|
|
3574
|
+
function extractEcmaScriptBindings(root, filePath, workspaceFiles) {
|
|
3575
|
+
const imports = extractEcmaScriptImportBindings(root, filePath, workspaceFiles);
|
|
3576
|
+
const reexports = extractEcmaScriptReexportBindings(root, filePath, workspaceFiles);
|
|
3577
|
+
return [...imports, ...reexports];
|
|
3578
|
+
}
|
|
3579
|
+
var init_ecma_script = __esm({
|
|
3580
|
+
"src/code-nav/symbol-index/imports/ecma-script.ts"() {
|
|
3581
|
+
"use strict";
|
|
3582
|
+
init_ecma_script_imports();
|
|
3583
|
+
init_ecma_script_exports();
|
|
3584
|
+
init_ecma_script_imports();
|
|
3585
|
+
}
|
|
3586
|
+
});
|
|
3587
|
+
|
|
3588
|
+
// src/code-nav/symbol-index/imports/go.ts
|
|
3589
|
+
function collectImportSpec(out, filePath, workspaceFiles, spec) {
|
|
3590
|
+
const pathNode = spec.childForFieldName("path");
|
|
3591
|
+
if (!pathNode) return;
|
|
3592
|
+
const modulePath = stringLiteralText(pathNode);
|
|
3593
|
+
const nameNode = spec.childForFieldName("name");
|
|
3594
|
+
if (nameNode) {
|
|
3595
|
+
pushBinding(out, filePath, workspaceFiles, modulePath, nameNode.text, nameNode.text, "namespace", nameNode);
|
|
3596
|
+
return;
|
|
3597
|
+
}
|
|
3598
|
+
const localName = modulePath.split("/").filter(Boolean).at(-1) ?? modulePath;
|
|
3599
|
+
pushBinding(out, filePath, workspaceFiles, modulePath, localName, localName, "namespace", pathNode);
|
|
3600
|
+
}
|
|
3601
|
+
function extractGoImportBindings(root, filePath, workspaceFiles) {
|
|
3602
|
+
const out = [];
|
|
3603
|
+
for (const node of root.descendantsOfType("import_declaration")) {
|
|
3604
|
+
for (const spec of node.descendantsOfType("import_spec")) {
|
|
3605
|
+
collectImportSpec(out, filePath, workspaceFiles, spec);
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
return out;
|
|
3609
|
+
}
|
|
3610
|
+
var init_go2 = __esm({
|
|
3611
|
+
"src/code-nav/symbol-index/imports/go.ts"() {
|
|
3612
|
+
"use strict";
|
|
3613
|
+
init_shared2();
|
|
3614
|
+
}
|
|
3615
|
+
});
|
|
3616
|
+
|
|
3617
|
+
// src/code-nav/symbol-index/imports/java.ts
|
|
3618
|
+
function localNameFromImport(nameNode) {
|
|
3619
|
+
return nameNode.text.split(".").at(-1) ?? nameNode.text;
|
|
3620
|
+
}
|
|
3621
|
+
function collectImportDeclaration(out, filePath, workspaceFiles, node) {
|
|
3622
|
+
for (const child of node.namedChildren) {
|
|
3623
|
+
if (child.type === "scoped_identifier" || child.type === "identifier") {
|
|
3624
|
+
const sourceName = child.text;
|
|
3625
|
+
const localName = localNameFromImport(child);
|
|
3626
|
+
pushBinding(out, filePath, workspaceFiles, sourceName, localName, sourceName, "named", child);
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
function extractJavaImportBindings(root, filePath, workspaceFiles) {
|
|
3631
|
+
const out = [];
|
|
3632
|
+
for (const node of root.descendantsOfType("import_declaration")) {
|
|
3633
|
+
collectImportDeclaration(out, filePath, workspaceFiles, node);
|
|
3634
|
+
}
|
|
3635
|
+
return out;
|
|
3636
|
+
}
|
|
3637
|
+
var init_java2 = __esm({
|
|
3638
|
+
"src/code-nav/symbol-index/imports/java.ts"() {
|
|
3639
|
+
"use strict";
|
|
3640
|
+
init_shared2();
|
|
3641
|
+
}
|
|
3642
|
+
});
|
|
3643
|
+
|
|
3644
|
+
// src/code-nav/symbol-index/imports/python.ts
|
|
3645
|
+
function dottedNameText(node) {
|
|
3646
|
+
return node.text.replace(/\s+/g, "");
|
|
3647
|
+
}
|
|
3648
|
+
function collectImportStatement(out, filePath, workspaceFiles, node) {
|
|
3649
|
+
const nameNode = node.childForFieldName("name");
|
|
3650
|
+
if (!nameNode) return;
|
|
3651
|
+
const moduleName = dottedNameText(nameNode);
|
|
3652
|
+
const localName = moduleName.split(".").at(-1) ?? moduleName;
|
|
3653
|
+
pushBinding(out, filePath, workspaceFiles, moduleName, localName, localName, "namespace", nameNode);
|
|
3654
|
+
}
|
|
3655
|
+
function collectImportFromStatement(out, filePath, workspaceFiles, node) {
|
|
3656
|
+
const moduleNode = node.childForFieldName("module_name");
|
|
3657
|
+
const moduleName = moduleNode ? dottedNameText(moduleNode) : "";
|
|
3658
|
+
for (const child of node.namedChildren) {
|
|
3659
|
+
if (child.type !== "dotted_name" && child.type !== "aliased_import") continue;
|
|
3660
|
+
if (child === moduleNode) continue;
|
|
3661
|
+
if (child.type === "dotted_name") {
|
|
3662
|
+
const sourceName2 = dottedNameText(child);
|
|
3663
|
+
const localName2 = sourceName2.split(".").at(-1) ?? sourceName2;
|
|
3664
|
+
pushBinding(out, filePath, workspaceFiles, moduleName, localName2, sourceName2, "named", child);
|
|
3665
|
+
continue;
|
|
3666
|
+
}
|
|
3667
|
+
const nameNode = child.childForFieldName("name");
|
|
3668
|
+
const aliasNode = child.childForFieldName("alias");
|
|
3669
|
+
if (!nameNode) continue;
|
|
3670
|
+
const sourceName = dottedNameText(nameNode);
|
|
3671
|
+
const localName = aliasNode ? aliasNode.text : sourceName.split(".").at(-1) ?? sourceName;
|
|
3672
|
+
pushBinding(out, filePath, workspaceFiles, moduleName, localName, sourceName, "named", aliasNode ?? nameNode);
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
function extractPythonImportBindings(root, filePath, workspaceFiles) {
|
|
3676
|
+
const out = [];
|
|
3677
|
+
for (const node of root.descendantsOfType("import_statement")) {
|
|
3678
|
+
collectImportStatement(out, filePath, workspaceFiles, node);
|
|
3679
|
+
}
|
|
3680
|
+
for (const node of root.descendantsOfType("import_from_statement")) {
|
|
3681
|
+
collectImportFromStatement(out, filePath, workspaceFiles, node);
|
|
3682
|
+
}
|
|
3683
|
+
return out;
|
|
3684
|
+
}
|
|
3685
|
+
var init_python2 = __esm({
|
|
3686
|
+
"src/code-nav/symbol-index/imports/python.ts"() {
|
|
3687
|
+
"use strict";
|
|
3688
|
+
init_shared2();
|
|
3689
|
+
}
|
|
3690
|
+
});
|
|
3691
|
+
|
|
3692
|
+
// src/code-nav/symbol-index/imports/ruby.ts
|
|
3693
|
+
function collectRequireCall(out, filePath, workspaceFiles, node) {
|
|
3694
|
+
const methodNode = node.childForFieldName("method");
|
|
3695
|
+
if (!methodNode || methodNode.text !== "require" && methodNode.text !== "require_relative") return;
|
|
3696
|
+
const args = node.childForFieldName("arguments");
|
|
3697
|
+
const stringNode = args?.descendantsOfType("string")[0] ?? args?.descendantsOfType("string_content")[0];
|
|
3698
|
+
if (!stringNode) return;
|
|
3699
|
+
const modulePath = stringLiteralText(stringNode);
|
|
3700
|
+
const localName = modulePath.split("/").filter(Boolean).at(-1)?.replace(/\.rb$/, "") ?? modulePath;
|
|
3701
|
+
pushBinding(out, filePath, workspaceFiles, modulePath, localName, localName, "default", stringNode);
|
|
3702
|
+
}
|
|
3703
|
+
function extractRubyImportBindings(root, filePath, workspaceFiles) {
|
|
3704
|
+
const out = [];
|
|
3705
|
+
for (const node of root.descendantsOfType("call")) {
|
|
3706
|
+
collectRequireCall(out, filePath, workspaceFiles, node);
|
|
3707
|
+
}
|
|
3708
|
+
return out;
|
|
3709
|
+
}
|
|
3710
|
+
var init_ruby2 = __esm({
|
|
3711
|
+
"src/code-nav/symbol-index/imports/ruby.ts"() {
|
|
3712
|
+
"use strict";
|
|
3713
|
+
init_shared2();
|
|
3714
|
+
}
|
|
3715
|
+
});
|
|
3716
|
+
|
|
3717
|
+
// src/code-nav/symbol-index/imports/rust.ts
|
|
3718
|
+
function identifierFromUseTree(node) {
|
|
3719
|
+
if (node.type === "identifier" || node.type === "type_identifier") return node;
|
|
3720
|
+
const nameNode = node.childForFieldName("name");
|
|
3721
|
+
if (nameNode) return nameNode;
|
|
3722
|
+
for (const child of node.namedChildren) {
|
|
3723
|
+
const hit = identifierFromUseTree(child);
|
|
3724
|
+
if (hit) return hit;
|
|
3725
|
+
}
|
|
3726
|
+
return null;
|
|
3727
|
+
}
|
|
3728
|
+
function useDeclarationIsPublic(node) {
|
|
3729
|
+
return node.children.some((child) => child.type === "visibility_modifier" && child.text === "pub");
|
|
3730
|
+
}
|
|
3731
|
+
function collectUseTree(out, filePath, workspaceFiles, pathPrefix, node, importKind = "named") {
|
|
3732
|
+
if (node.type === "use_as_clause") {
|
|
3733
|
+
const pathNode = node.childForFieldName("path");
|
|
3734
|
+
const aliasNode = node.childForFieldName("alias");
|
|
3735
|
+
if (!pathNode || !aliasNode) return;
|
|
3736
|
+
const sourceName = identifierFromUseTree(pathNode)?.text ?? pathNode.text.split("::").at(-1) ?? "";
|
|
3737
|
+
pushBinding(out, filePath, workspaceFiles, pathPrefix, aliasNode.text, sourceName, importKind, aliasNode);
|
|
3738
|
+
return;
|
|
3739
|
+
}
|
|
3740
|
+
if (node.type === "identifier" || node.type === "type_identifier") {
|
|
3741
|
+
const sourceName = node.text;
|
|
3742
|
+
pushBinding(out, filePath, workspaceFiles, pathPrefix, sourceName, sourceName, importKind, node);
|
|
3743
|
+
return;
|
|
3744
|
+
}
|
|
3745
|
+
if (node.type === "scoped_identifier") {
|
|
3746
|
+
const nameNode = node.childForFieldName("name");
|
|
3747
|
+
if (!nameNode) return;
|
|
3748
|
+
const sourceName = nameNode.text;
|
|
3749
|
+
pushBinding(out, filePath, workspaceFiles, pathPrefix, sourceName, sourceName, importKind, nameNode);
|
|
3750
|
+
return;
|
|
3751
|
+
}
|
|
3752
|
+
if (node.type === "use_list") {
|
|
3753
|
+
for (const child of node.namedChildren) {
|
|
3754
|
+
collectUseTree(out, filePath, workspaceFiles, pathPrefix, child, importKind);
|
|
3755
|
+
}
|
|
3756
|
+
return;
|
|
3757
|
+
}
|
|
3758
|
+
if (node.type === "scoped_use_list") {
|
|
3759
|
+
const pathNode = node.childForFieldName("path");
|
|
3760
|
+
const nextPrefix = pathNode ? `${pathPrefix}${pathNode.text}::` : pathPrefix;
|
|
3761
|
+
for (const child of node.namedChildren) {
|
|
3762
|
+
if (child === pathNode) continue;
|
|
3763
|
+
collectUseTree(out, filePath, workspaceFiles, nextPrefix, child, importKind);
|
|
3764
|
+
}
|
|
3765
|
+
return;
|
|
3766
|
+
}
|
|
3767
|
+
for (const child of node.namedChildren) {
|
|
3768
|
+
collectUseTree(out, filePath, workspaceFiles, pathPrefix, child, importKind);
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
function extractRustImportBindings(root, filePath, workspaceFiles) {
|
|
3772
|
+
const out = [];
|
|
3773
|
+
for (const node of root.descendantsOfType("use_declaration")) {
|
|
3774
|
+
const argument = node.childForFieldName("argument");
|
|
3775
|
+
if (!argument) continue;
|
|
3776
|
+
const importKind = useDeclarationIsPublic(node) ? "reexport" : "named";
|
|
3777
|
+
collectUseTree(out, filePath, workspaceFiles, "", argument, importKind);
|
|
3778
|
+
}
|
|
3779
|
+
return out;
|
|
3780
|
+
}
|
|
3781
|
+
var init_rust2 = __esm({
|
|
3782
|
+
"src/code-nav/symbol-index/imports/rust.ts"() {
|
|
3783
|
+
"use strict";
|
|
3784
|
+
init_shared2();
|
|
3785
|
+
}
|
|
3786
|
+
});
|
|
3787
|
+
|
|
3788
|
+
// src/code-nav/symbol-index/imports/index.ts
|
|
3789
|
+
async function extractImportBindingsFromSource(filePath, source, workspaceFiles) {
|
|
3790
|
+
const languageKey = getLanguageKeyForFilePath(filePath);
|
|
3791
|
+
if (!languageKey) return [];
|
|
3792
|
+
const extract = EXTRACTORS_BY_LANGUAGE_KEY[languageKey];
|
|
3793
|
+
if (!extract) return [];
|
|
3794
|
+
const parsed = await parseSourceRoot(filePath, source);
|
|
3795
|
+
if (!parsed) return [];
|
|
3796
|
+
try {
|
|
3797
|
+
await yieldToEventLoop();
|
|
3798
|
+
const yieldState = createCodeNavYieldState();
|
|
3799
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
3800
|
+
const bindings = extract(parsed.root, filePath, workspaceFiles);
|
|
3801
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
3802
|
+
return bindings;
|
|
3803
|
+
} finally {
|
|
3804
|
+
parsed.cleanup();
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
var EXTRACTORS_BY_LANGUAGE_KEY;
|
|
3808
|
+
var init_imports = __esm({
|
|
3809
|
+
"src/code-nav/symbol-index/imports/index.ts"() {
|
|
3810
|
+
"use strict";
|
|
3811
|
+
init_language_registry();
|
|
3812
|
+
init_parser_runtime();
|
|
3813
|
+
init_yield_during_work();
|
|
3814
|
+
init_yield_to_event_loop();
|
|
3815
|
+
init_c2();
|
|
3816
|
+
init_cpp2();
|
|
3817
|
+
init_ecma_script();
|
|
3818
|
+
init_go2();
|
|
3819
|
+
init_java2();
|
|
3820
|
+
init_python2();
|
|
3821
|
+
init_ruby2();
|
|
3822
|
+
init_rust2();
|
|
3823
|
+
EXTRACTORS_BY_LANGUAGE_KEY = {
|
|
3824
|
+
javascript: extractEcmaScriptBindings,
|
|
3825
|
+
typescript: extractEcmaScriptBindings,
|
|
3826
|
+
tsx: extractEcmaScriptBindings,
|
|
3827
|
+
python: extractPythonImportBindings,
|
|
3828
|
+
go: extractGoImportBindings,
|
|
3829
|
+
rust: extractRustImportBindings,
|
|
3830
|
+
ruby: extractRubyImportBindings,
|
|
3831
|
+
java: extractJavaImportBindings,
|
|
3832
|
+
c: extractCIncludeBindings,
|
|
3833
|
+
cpp: extractCppImportBindings
|
|
3834
|
+
};
|
|
3835
|
+
}
|
|
3836
|
+
});
|
|
3837
|
+
|
|
3838
|
+
// src/code-nav/symbol-index/build/read-index-source.ts
|
|
3839
|
+
var MAX_INDEX_FILE_BYTES;
|
|
3840
|
+
var init_read_index_source = __esm({
|
|
3841
|
+
"src/code-nav/symbol-index/build/read-index-source.ts"() {
|
|
3842
|
+
"use strict";
|
|
3843
|
+
init_cli_process_interrupt();
|
|
3844
|
+
init_code_nav_cache_database();
|
|
3845
|
+
MAX_INDEX_FILE_BYTES = 512 * 1024;
|
|
3846
|
+
}
|
|
3847
|
+
});
|
|
3848
|
+
|
|
3849
|
+
// src/code-nav/symbol-index/build/workspace-files.ts
|
|
3850
|
+
function listWorkspaceFiles(db, workspacePath, includePath) {
|
|
3851
|
+
const files = /* @__PURE__ */ new Set([includePath.replace(/\\/g, "/")]);
|
|
3852
|
+
const normalizedWorkspace = normalizeResolvedPath(workspacePath);
|
|
3853
|
+
const parentRow = db.get("SELECT id FROM file_index_parent_path WHERE path = ?", [normalizedWorkspace]);
|
|
3854
|
+
if (parentRow != null) {
|
|
3855
|
+
const fromIndex = db.all("SELECT path FROM file_index_child_path WHERE parent_id = ?", [
|
|
3856
|
+
Number(parentRow.id)
|
|
3857
|
+
]);
|
|
3858
|
+
for (const row of fromIndex) files.add(row.path.replace(/\\/g, "/"));
|
|
3859
|
+
}
|
|
3860
|
+
const ctx = getSymbolIndexParentContext(db, normalizedWorkspace);
|
|
3861
|
+
if (ctx != null) {
|
|
3862
|
+
for (const filePath of listEffectiveIndexedFilePaths(db, ctx)) {
|
|
3863
|
+
files.add(filePath.replace(/\\/g, "/"));
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
return files;
|
|
3867
|
+
}
|
|
3868
|
+
var init_workspace_files = __esm({
|
|
3869
|
+
"src/code-nav/symbol-index/build/workspace-files.ts"() {
|
|
3870
|
+
"use strict";
|
|
3871
|
+
init_normalize_resolved_path();
|
|
3872
|
+
init_symbol_index_sqlite();
|
|
3873
|
+
init_symbol_parent_file_map();
|
|
3874
|
+
}
|
|
3875
|
+
});
|
|
3876
|
+
|
|
3877
|
+
// src/code-nav/symbol-index/build/extract-file-symbol-data.ts
|
|
3878
|
+
import fs12 from "node:fs";
|
|
3879
|
+
import path15 from "node:path";
|
|
3880
|
+
async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride) {
|
|
3881
|
+
await yieldForBridgeInteractivePriority();
|
|
3882
|
+
const absPath = path15.join(resolved, relPath);
|
|
3883
|
+
let tags = [];
|
|
3884
|
+
let source = null;
|
|
3885
|
+
if (isCodeNavSupportedPath(relPath) && !await isPathGitIgnored(resolved, relPath)) {
|
|
3886
|
+
try {
|
|
3887
|
+
const stat = await fs12.promises.stat(absPath);
|
|
3888
|
+
if (stat.isFile() && stat.size <= MAX_INDEX_FILE_BYTES) {
|
|
3889
|
+
source = await fs12.promises.readFile(absPath, "utf8");
|
|
3890
|
+
await yieldForBridgeInteractivePriority();
|
|
3891
|
+
tags = await extractTagsFromSource(relPath, source);
|
|
3892
|
+
}
|
|
3893
|
+
} catch (err) {
|
|
3894
|
+
if (isSymbolIndexDeferredError(err)) throw err;
|
|
3895
|
+
tags = [];
|
|
3896
|
+
source = null;
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
await yieldForBridgeInteractivePriority();
|
|
3900
|
+
const workspaceFiles = workspaceFilesOverride ?? await withCodeNavCacheSqlite((db) => listWorkspaceFiles(db, resolved, relPath));
|
|
3901
|
+
const imports = source != null ? await extractImportBindingsFromSource(relPath, source, workspaceFiles) : [];
|
|
3902
|
+
const yieldState = createCodeNavYieldState();
|
|
3903
|
+
return {
|
|
3904
|
+
source,
|
|
3905
|
+
tags: await enrichTagsWithModulePathsAsync(tags, relPath, workspaceFiles, yieldState),
|
|
3906
|
+
imports
|
|
3907
|
+
};
|
|
3908
|
+
}
|
|
3909
|
+
var init_extract_file_symbol_data = __esm({
|
|
3910
|
+
"src/code-nav/symbol-index/build/extract-file-symbol-data.ts"() {
|
|
3911
|
+
"use strict";
|
|
3912
|
+
init_file_browser_in_flight();
|
|
3913
|
+
init_deferred_indexing();
|
|
3914
|
+
init_code_nav_cache_database();
|
|
3915
|
+
init_enrich_tag_module_paths_async();
|
|
3916
|
+
init_gitignore_filter();
|
|
3917
|
+
init_language_registry();
|
|
3918
|
+
init_parser_runtime();
|
|
3919
|
+
init_yield_during_work();
|
|
3920
|
+
init_imports();
|
|
3921
|
+
init_read_index_source();
|
|
3922
|
+
init_workspace_files();
|
|
3923
|
+
}
|
|
3924
|
+
});
|
|
3925
|
+
|
|
3926
|
+
// src/code-nav/symbol-index/build/index-one-symbol-file-for-build.ts
|
|
3927
|
+
async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
|
|
3928
|
+
await yieldForBridgeInteractivePriority();
|
|
3929
|
+
const data = await extractFileSymbolData(resolved, relPath, workspaceFiles);
|
|
3930
|
+
let entry = {
|
|
3931
|
+
relPath,
|
|
3932
|
+
source: data.source,
|
|
3933
|
+
tags: data.tags,
|
|
3934
|
+
imports: data.imports
|
|
3935
|
+
};
|
|
3936
|
+
if (data.imports.some((binding) => binding.importKind === "star")) {
|
|
3937
|
+
await yieldForBridgeInteractivePriority();
|
|
3938
|
+
entry = await withCodeNavCacheSqlite((db) => {
|
|
3939
|
+
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
3940
|
+
if (ctx == null) return entry;
|
|
3941
|
+
const resolveEntry = (filePath) => loadIndexedFileEntry(db, ctx, filePath);
|
|
3942
|
+
return expandStarReexportForFile(entry, resolveEntry);
|
|
3943
|
+
});
|
|
3944
|
+
entry.source = data.source;
|
|
3945
|
+
}
|
|
3946
|
+
await withSymbolIndexSqliteLock(async () => {
|
|
3947
|
+
await yieldForBridgeInteractivePriority();
|
|
3948
|
+
await persistSymbolIndexFileAsync(resolved, relPath, entry.source, entry.tags, entry.imports);
|
|
3949
|
+
});
|
|
3950
|
+
}
|
|
3951
|
+
var init_index_one_symbol_file_for_build = __esm({
|
|
3952
|
+
"src/code-nav/symbol-index/build/index-one-symbol-file-for-build.ts"() {
|
|
3953
|
+
"use strict";
|
|
3954
|
+
init_file_browser_in_flight();
|
|
3955
|
+
init_code_nav_cache_database();
|
|
3956
|
+
init_expand_star_reexports();
|
|
3957
|
+
init_persist_single_file();
|
|
3958
|
+
init_symbol_index_sqlite();
|
|
3959
|
+
init_symbol_index_sqlite_lock();
|
|
3960
|
+
init_extract_file_symbol_data();
|
|
3961
|
+
init_load_indexed_file_entry();
|
|
3962
|
+
}
|
|
3963
|
+
});
|
|
3964
|
+
|
|
3965
|
+
// src/code-nav/symbol-index/build/normalize-symbol-index-rel-path.ts
|
|
3966
|
+
function normalizeSymbolIndexRelPath(filePath) {
|
|
3967
|
+
return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3968
|
+
}
|
|
3969
|
+
var init_normalize_symbol_index_rel_path = __esm({
|
|
3970
|
+
"src/code-nav/symbol-index/build/normalize-symbol-index-rel-path.ts"() {
|
|
3971
|
+
"use strict";
|
|
3972
|
+
}
|
|
3973
|
+
});
|
|
3974
|
+
|
|
3975
|
+
// src/code-nav/symbol-index/build/ensure-symbol-index-file-impl.ts
|
|
3976
|
+
async function ensureSymbolIndexFileImpl(parentPath, filePath, opts) {
|
|
3977
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
3978
|
+
const relPath = normalizeSymbolIndexRelPath(filePath);
|
|
3979
|
+
if (!relPath) return false;
|
|
3980
|
+
const importDepth = opts?.importDepth ?? 0;
|
|
3981
|
+
await withCodeNavCacheSqlite((db) => {
|
|
3982
|
+
upsertSymbolIndexParentPath(db, resolved);
|
|
3983
|
+
});
|
|
3984
|
+
if (!await symbolIndexFileIsReadyAsync(resolved, relPath)) {
|
|
3985
|
+
await indexOneSymbolFileForBuild(resolved, relPath, void 0);
|
|
3986
|
+
}
|
|
3987
|
+
if (importDepth > 0 && await symbolIndexFileIsReadyAsync(resolved, relPath)) {
|
|
3988
|
+
const targets = (await listDirectImportTargetsForFileAsync(resolved, relPath)).slice(
|
|
3989
|
+
0,
|
|
3990
|
+
MAX_IMPORT_PREFETCH_COUNT
|
|
3991
|
+
);
|
|
3992
|
+
for (const target of targets) {
|
|
3993
|
+
if (!await symbolIndexFileIsReadyAsync(resolved, target)) {
|
|
3994
|
+
await ensureSymbolIndexFileImpl(resolved, target, { importDepth: importDepth - 1 });
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
}
|
|
3998
|
+
return await symbolIndexFileIsReadyAsync(resolved, relPath);
|
|
3999
|
+
}
|
|
4000
|
+
var MAX_IMPORT_PREFETCH_COUNT;
|
|
4001
|
+
var init_ensure_symbol_index_file_impl = __esm({
|
|
4002
|
+
"src/code-nav/symbol-index/build/ensure-symbol-index-file-impl.ts"() {
|
|
4003
|
+
"use strict";
|
|
4004
|
+
init_normalize_resolved_path();
|
|
4005
|
+
init_code_nav_cache_database();
|
|
4006
|
+
init_list_direct_import_targets();
|
|
4007
|
+
init_symbol_index_file_ready();
|
|
4008
|
+
init_symbol_index_sqlite();
|
|
4009
|
+
init_index_one_symbol_file_for_build();
|
|
4010
|
+
init_normalize_symbol_index_rel_path();
|
|
4011
|
+
init_index_one_symbol_file_for_build();
|
|
4012
|
+
MAX_IMPORT_PREFETCH_COUNT = 8;
|
|
4013
|
+
}
|
|
4014
|
+
});
|
|
4015
|
+
|
|
4016
|
+
// src/code-nav/symbol-index/build/build-symbol-index-impl.ts
|
|
4017
|
+
async function buildSymbolIndexImpl(parentPath) {
|
|
4018
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
4019
|
+
let clearRemaining = true;
|
|
4020
|
+
while (clearRemaining) {
|
|
4021
|
+
await withSymbolIndexSqliteLock(async () => {
|
|
4022
|
+
clearRemaining = await withCodeNavCacheSqlite(
|
|
4023
|
+
(db) => runCodeNavCacheWriteTransaction(db, () => {
|
|
4024
|
+
upsertSymbolIndexParentPath(db, resolved);
|
|
4025
|
+
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
4026
|
+
return ctx == null ? false : clearSymbolIndexParentDataBatch(db, ctx, SYMBOL_PARENT_CLEAR_BATCH_SIZE);
|
|
4027
|
+
})
|
|
4028
|
+
);
|
|
4029
|
+
});
|
|
4030
|
+
}
|
|
4031
|
+
const workspaceFiles = /* @__PURE__ */ new Set();
|
|
4032
|
+
const walkState = createWalkYieldState();
|
|
4033
|
+
const yieldState = createCodeNavYieldState();
|
|
4034
|
+
await walkCodeNavFilesAsync(
|
|
4035
|
+
resolved,
|
|
4036
|
+
async (relPath) => {
|
|
4037
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
4038
|
+
workspaceFiles.add(relPath);
|
|
4039
|
+
},
|
|
4040
|
+
walkState
|
|
4041
|
+
);
|
|
4042
|
+
let fileCount = 0;
|
|
4043
|
+
await walkCodeNavFilesAsync(
|
|
4044
|
+
resolved,
|
|
4045
|
+
async (relPath) => {
|
|
4046
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
4047
|
+
await indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles);
|
|
4048
|
+
fileCount += 1;
|
|
4049
|
+
},
|
|
4050
|
+
walkState
|
|
4051
|
+
);
|
|
4052
|
+
return { fileCount, tagCount: 0 };
|
|
4053
|
+
}
|
|
4054
|
+
var SYMBOL_PARENT_CLEAR_BATCH_SIZE;
|
|
4055
|
+
var init_build_symbol_index_impl = __esm({
|
|
4056
|
+
"src/code-nav/symbol-index/build/build-symbol-index-impl.ts"() {
|
|
4057
|
+
"use strict";
|
|
4058
|
+
init_normalize_resolved_path();
|
|
4059
|
+
init_code_nav_cache_database();
|
|
4060
|
+
init_code_nav_cache_sqlite_transaction();
|
|
4061
|
+
init_yield_during_work();
|
|
4062
|
+
init_walk_code_nav_files();
|
|
4063
|
+
init_symbol_index_sqlite();
|
|
4064
|
+
init_symbol_index_sqlite_lock();
|
|
4065
|
+
init_ensure_symbol_index_file_impl();
|
|
4066
|
+
SYMBOL_PARENT_CLEAR_BATCH_SIZE = 256;
|
|
4067
|
+
}
|
|
4068
|
+
});
|
|
4069
|
+
|
|
4070
|
+
// src/code-nav/symbol-index/build/build-symbol-index-host.ts
|
|
4071
|
+
var init_build_symbol_index_host = __esm({
|
|
4072
|
+
"src/code-nav/symbol-index/build/build-symbol-index-host.ts"() {
|
|
4073
|
+
"use strict";
|
|
4074
|
+
init_build_symbol_index_impl();
|
|
4075
|
+
}
|
|
4076
|
+
});
|
|
4077
|
+
|
|
4078
|
+
// src/code-nav/symbol-index/build/ensure-symbol-index-file-host.ts
|
|
4079
|
+
var init_ensure_symbol_index_file_host = __esm({
|
|
4080
|
+
"src/code-nav/symbol-index/build/ensure-symbol-index-file-host.ts"() {
|
|
4081
|
+
"use strict";
|
|
4082
|
+
init_ensure_symbol_index_file_impl();
|
|
4083
|
+
}
|
|
4084
|
+
});
|
|
4085
|
+
|
|
4086
|
+
// src/code-nav/symbol-index/lifecycle/normalize-symbol-index-path.ts
|
|
4087
|
+
var init_normalize_symbol_index_path = __esm({
|
|
4088
|
+
"src/code-nav/symbol-index/lifecycle/normalize-symbol-index-path.ts"() {
|
|
4089
|
+
"use strict";
|
|
4090
|
+
}
|
|
4091
|
+
});
|
|
4092
|
+
|
|
4093
|
+
// src/code-nav/symbol-index/build/update-symbol-index-file-impl.ts
|
|
4094
|
+
async function updateSymbolIndexRelPathImpl(parentPath, relPath) {
|
|
4095
|
+
const normalizedRel = relPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
4096
|
+
if (!normalizedRel) return;
|
|
4097
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
4098
|
+
const { source, tags, imports } = await extractFileSymbolData(resolved, normalizedRel);
|
|
4099
|
+
await yieldToEventLoop();
|
|
4100
|
+
await withSymbolIndexSqliteLock(async () => {
|
|
4101
|
+
await persistSymbolIndexFileAsync(resolved, normalizedRel, source, tags, imports);
|
|
4102
|
+
});
|
|
4103
|
+
}
|
|
4104
|
+
async function removeSymbolIndexRelPathImpl(parentPath, relPath) {
|
|
4105
|
+
const normalizedRel = relPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
4106
|
+
if (!normalizedRel) return;
|
|
4107
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
4108
|
+
await withSymbolIndexSqliteLock(async () => {
|
|
4109
|
+
await removeSymbolIndexFileAsync(resolved, normalizedRel);
|
|
4110
|
+
});
|
|
4111
|
+
}
|
|
4112
|
+
var init_update_symbol_index_file_impl = __esm({
|
|
4113
|
+
"src/code-nav/symbol-index/build/update-symbol-index-file-impl.ts"() {
|
|
4114
|
+
"use strict";
|
|
4115
|
+
init_normalize_resolved_path();
|
|
4116
|
+
init_yield_to_event_loop();
|
|
4117
|
+
init_normalize_symbol_index_path();
|
|
4118
|
+
init_persist_single_file();
|
|
4119
|
+
init_symbol_index_sqlite_lock();
|
|
4120
|
+
init_extract_file_symbol_data();
|
|
4121
|
+
}
|
|
4122
|
+
});
|
|
4123
|
+
|
|
4124
|
+
// src/code-nav/symbol-index/build/update-symbol-index-file-host.ts
|
|
4125
|
+
var init_update_symbol_index_file_host = __esm({
|
|
4126
|
+
"src/code-nav/symbol-index/build/update-symbol-index-file-host.ts"() {
|
|
4127
|
+
"use strict";
|
|
4128
|
+
init_update_symbol_index_file_impl();
|
|
4129
|
+
}
|
|
4130
|
+
});
|
|
4131
|
+
|
|
4132
|
+
// src/code-nav/symbol-index/worker/symbol-index-worker-host-post.ts
|
|
4133
|
+
function postSafe(port, message) {
|
|
4134
|
+
try {
|
|
4135
|
+
port.postMessage(message);
|
|
4136
|
+
} catch {
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4139
|
+
var init_symbol_index_worker_host_post = __esm({
|
|
4140
|
+
"src/code-nav/symbol-index/worker/symbol-index-worker-host-post.ts"() {
|
|
4141
|
+
"use strict";
|
|
4142
|
+
}
|
|
4143
|
+
});
|
|
4144
|
+
|
|
4145
|
+
// src/code-nav/symbol-index/worker/symbol-index-worker-host-index-handlers.ts
|
|
4146
|
+
function postWorkerError(port, requestId, err) {
|
|
4147
|
+
postSafe(port, {
|
|
4148
|
+
type: "error",
|
|
4149
|
+
requestId,
|
|
4150
|
+
message: err instanceof Error ? err.message : String(err)
|
|
4151
|
+
});
|
|
4152
|
+
}
|
|
4153
|
+
async function handleIndexWorkerMessage(port, msg) {
|
|
4154
|
+
switch (msg.type) {
|
|
4155
|
+
case "buildFull": {
|
|
4156
|
+
try {
|
|
4157
|
+
const result = await buildSymbolIndexImpl(msg.parentPath);
|
|
4158
|
+
postSafe(port, { type: "buildComplete", requestId: msg.requestId, ...result });
|
|
4159
|
+
} catch (err) {
|
|
4160
|
+
postWorkerError(port, msg.requestId, err);
|
|
4161
|
+
}
|
|
4162
|
+
return;
|
|
4163
|
+
}
|
|
4164
|
+
case "updateFile": {
|
|
4165
|
+
try {
|
|
4166
|
+
await updateSymbolIndexRelPathImpl(msg.parentPath, msg.relPath);
|
|
4167
|
+
postSafe(port, { type: "updateComplete", requestId: msg.requestId });
|
|
4168
|
+
} catch (err) {
|
|
4169
|
+
postWorkerError(port, msg.requestId, err);
|
|
4170
|
+
}
|
|
4171
|
+
return;
|
|
4172
|
+
}
|
|
4173
|
+
case "removeFile": {
|
|
4174
|
+
try {
|
|
4175
|
+
await removeSymbolIndexRelPathImpl(msg.parentPath, msg.relPath);
|
|
4176
|
+
postSafe(port, { type: "removeComplete", requestId: msg.requestId });
|
|
4177
|
+
} catch (err) {
|
|
4178
|
+
postWorkerError(port, msg.requestId, err);
|
|
4179
|
+
}
|
|
4180
|
+
return;
|
|
4181
|
+
}
|
|
4182
|
+
case "ensureFile": {
|
|
4183
|
+
try {
|
|
4184
|
+
const ready = await ensureSymbolIndexFileImpl(msg.parentPath, msg.filePath, {
|
|
4185
|
+
importDepth: msg.importDepth
|
|
4186
|
+
});
|
|
4187
|
+
postSafe(port, { type: "ensureComplete", requestId: msg.requestId, ready });
|
|
4188
|
+
} catch (err) {
|
|
4189
|
+
postWorkerError(port, msg.requestId, err);
|
|
4190
|
+
}
|
|
4191
|
+
return;
|
|
4192
|
+
}
|
|
4193
|
+
default:
|
|
4194
|
+
return;
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
var init_symbol_index_worker_host_index_handlers = __esm({
|
|
4198
|
+
"src/code-nav/symbol-index/worker/symbol-index-worker-host-index-handlers.ts"() {
|
|
4199
|
+
"use strict";
|
|
4200
|
+
init_build_symbol_index_host();
|
|
4201
|
+
init_ensure_symbol_index_file_host();
|
|
4202
|
+
init_update_symbol_index_file_host();
|
|
4203
|
+
init_symbol_index_worker_host_post();
|
|
4204
|
+
}
|
|
4205
|
+
});
|
|
4206
|
+
|
|
4207
|
+
// src/code-nav/symbol-index/scheduler/task-priority-heap.ts
|
|
4208
|
+
function higherPriority(a, b) {
|
|
4209
|
+
return a.priority > b.priority;
|
|
4210
|
+
}
|
|
4211
|
+
var SymbolIndexTaskPriorityHeap;
|
|
4212
|
+
var init_task_priority_heap = __esm({
|
|
4213
|
+
"src/code-nav/symbol-index/scheduler/task-priority-heap.ts"() {
|
|
4214
|
+
"use strict";
|
|
4215
|
+
SymbolIndexTaskPriorityHeap = class {
|
|
4216
|
+
heap = [];
|
|
4217
|
+
clear() {
|
|
4218
|
+
this.heap.length = 0;
|
|
4219
|
+
}
|
|
4220
|
+
push(task) {
|
|
4221
|
+
this.heap.push(task);
|
|
4222
|
+
let i = this.heap.length - 1;
|
|
4223
|
+
while (i > 0) {
|
|
4224
|
+
const parent = Math.floor((i - 1) / 2);
|
|
4225
|
+
if (!higherPriority(this.heap[i], this.heap[parent])) break;
|
|
4226
|
+
this.swap(i, parent);
|
|
4227
|
+
i = parent;
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
pop() {
|
|
4231
|
+
if (this.heap.length === 0) return void 0;
|
|
4232
|
+
const top = this.heap[0];
|
|
4233
|
+
const last = this.heap.pop();
|
|
4234
|
+
if (this.heap.length > 0) {
|
|
4235
|
+
this.heap[0] = last;
|
|
4236
|
+
this.sink(0);
|
|
4237
|
+
}
|
|
4238
|
+
return top;
|
|
4239
|
+
}
|
|
4240
|
+
get size() {
|
|
4241
|
+
return this.heap.length;
|
|
4242
|
+
}
|
|
4243
|
+
sink(start) {
|
|
4244
|
+
let i = start;
|
|
4245
|
+
while (true) {
|
|
4246
|
+
const left = i * 2 + 1;
|
|
4247
|
+
const right = left + 1;
|
|
4248
|
+
let best = i;
|
|
4249
|
+
if (left < this.heap.length && higherPriority(this.heap[left], this.heap[best])) best = left;
|
|
4250
|
+
if (right < this.heap.length && higherPriority(this.heap[right], this.heap[best])) best = right;
|
|
4251
|
+
if (best === i) break;
|
|
4252
|
+
this.swap(i, best);
|
|
4253
|
+
i = best;
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
swap(i, j) {
|
|
4257
|
+
const tmp = this.heap[i];
|
|
4258
|
+
this.heap[i] = this.heap[j];
|
|
4259
|
+
this.heap[j] = tmp;
|
|
4260
|
+
}
|
|
4261
|
+
};
|
|
4262
|
+
}
|
|
4263
|
+
});
|
|
4264
|
+
|
|
4265
|
+
// src/code-nav/symbol-index/scheduler/task-queue-types.ts
|
|
4266
|
+
function symbolIndexTaskKey(parentPath, filePath) {
|
|
4267
|
+
return `${parentPath}\0${filePath}`;
|
|
4268
|
+
}
|
|
4269
|
+
var init_task_queue_types = __esm({
|
|
4270
|
+
"src/code-nav/symbol-index/scheduler/task-queue-types.ts"() {
|
|
4271
|
+
"use strict";
|
|
4272
|
+
}
|
|
4273
|
+
});
|
|
4274
|
+
|
|
4275
|
+
// src/code-nav/symbol-index/scheduler/task-queue-store.ts
|
|
4276
|
+
function setSymbolIndexWorkerRunning(running) {
|
|
4277
|
+
symbolIndexWorkerRunning = running;
|
|
4278
|
+
}
|
|
4279
|
+
function taskMatchesCurrentPending(task) {
|
|
4280
|
+
const current = pendingSymbolIndexTasks.get(symbolIndexTaskKey(task.parentPath, task.filePath));
|
|
4281
|
+
return current === task;
|
|
4282
|
+
}
|
|
4283
|
+
function pickNextSymbolIndexTask() {
|
|
4284
|
+
while (symbolIndexTaskHeap.size > 0) {
|
|
4285
|
+
const task = symbolIndexTaskHeap.pop();
|
|
4286
|
+
if (task == null || !taskMatchesCurrentPending(task)) continue;
|
|
4287
|
+
return task;
|
|
4288
|
+
}
|
|
4289
|
+
return void 0;
|
|
4290
|
+
}
|
|
4291
|
+
function addPendingSymbolIndexTask(task) {
|
|
4292
|
+
const key = symbolIndexTaskKey(task.parentPath, task.filePath);
|
|
4293
|
+
const existing = pendingSymbolIndexTasks.get(key);
|
|
4294
|
+
if (existing != null && existing.priority >= task.priority) return false;
|
|
4295
|
+
pendingSymbolIndexTasks.set(key, task);
|
|
4296
|
+
symbolIndexTaskHeap.push(task);
|
|
4297
|
+
return true;
|
|
4298
|
+
}
|
|
4299
|
+
function clearSymbolIndexHeapIfEmpty() {
|
|
4300
|
+
if (pendingSymbolIndexTasks.size === 0) symbolIndexTaskHeap.clear();
|
|
4301
|
+
}
|
|
4302
|
+
var pendingSymbolIndexTasks, symbolIndexTaskHeap, latestActiveSequenceByParent, symbolIndexWorkerRunning;
|
|
4303
|
+
var init_task_queue_store = __esm({
|
|
4304
|
+
"src/code-nav/symbol-index/scheduler/task-queue-store.ts"() {
|
|
4305
|
+
"use strict";
|
|
4306
|
+
init_task_priority_heap();
|
|
4307
|
+
init_task_queue_types();
|
|
4308
|
+
pendingSymbolIndexTasks = /* @__PURE__ */ new Map();
|
|
4309
|
+
symbolIndexTaskHeap = new SymbolIndexTaskPriorityHeap();
|
|
4310
|
+
latestActiveSequenceByParent = /* @__PURE__ */ new Map();
|
|
4311
|
+
symbolIndexWorkerRunning = false;
|
|
4312
|
+
}
|
|
4313
|
+
});
|
|
4314
|
+
|
|
4315
|
+
// src/code-nav/symbol-index/scheduler/task-queue-core.ts
|
|
4316
|
+
function enqueueSymbolIndexTaskInternal(parentPath, filePath, priority, sequence) {
|
|
4317
|
+
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
4318
|
+
const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
4319
|
+
if (!normalizedFile) return false;
|
|
4320
|
+
return addPendingSymbolIndexTask({
|
|
4321
|
+
parentPath: normalizedParent,
|
|
4322
|
+
filePath: normalizedFile,
|
|
4323
|
+
priority,
|
|
4324
|
+
sequence
|
|
4325
|
+
});
|
|
4326
|
+
}
|
|
4327
|
+
function markLatestActiveSymbolIndexTaskInternal(parentPath, sequence) {
|
|
4328
|
+
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
4329
|
+
const existing = latestActiveSequenceByParent.get(normalizedParent);
|
|
4330
|
+
if (existing != null && existing >= sequence) return;
|
|
4331
|
+
latestActiveSequenceByParent.set(normalizedParent, sequence);
|
|
4332
|
+
for (const [key, task] of pendingSymbolIndexTasks) {
|
|
4333
|
+
if (task.parentPath === normalizedParent && task.sequence != null && task.sequence < sequence) {
|
|
4334
|
+
pendingSymbolIndexTasks.delete(key);
|
|
4335
|
+
}
|
|
4336
|
+
}
|
|
4337
|
+
if (pendingSymbolIndexTasks.size === 0) symbolIndexTaskHeap.clear();
|
|
4338
|
+
}
|
|
4339
|
+
function deferBackgroundSymbolIndexTasks() {
|
|
4340
|
+
if (pendingSymbolIndexTasks.size === 0) return;
|
|
4341
|
+
for (const [key, task] of pendingSymbolIndexTasks) {
|
|
4342
|
+
if (task.priority <= SYMBOL_INDEX_BACKGROUND_PRIORITY_MAX) {
|
|
4343
|
+
pendingSymbolIndexTasks.delete(key);
|
|
4344
|
+
}
|
|
4345
|
+
}
|
|
4346
|
+
symbolIndexTaskHeap.clear();
|
|
4347
|
+
for (const task of pendingSymbolIndexTasks.values()) {
|
|
4348
|
+
symbolIndexTaskHeap.push(task);
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
var SYMBOL_INDEX_BACKGROUND_PRIORITY_MAX;
|
|
4352
|
+
var init_task_queue_core = __esm({
|
|
4353
|
+
"src/code-nav/symbol-index/scheduler/task-queue-core.ts"() {
|
|
4354
|
+
"use strict";
|
|
4355
|
+
init_normalize_resolved_path();
|
|
4356
|
+
init_task_queue_store();
|
|
4357
|
+
SYMBOL_INDEX_BACKGROUND_PRIORITY_MAX = 499999;
|
|
4358
|
+
}
|
|
4359
|
+
});
|
|
4360
|
+
|
|
4361
|
+
// src/code-nav/symbol-index/scheduler/task-queue-worker.ts
|
|
4362
|
+
async function runWorkerLoop() {
|
|
4363
|
+
if (symbolIndexWorkerRunning) return;
|
|
4364
|
+
setSymbolIndexWorkerRunning(true);
|
|
4365
|
+
try {
|
|
4366
|
+
const yieldState = createCodeNavYieldState();
|
|
4367
|
+
while (pendingSymbolIndexTasks.size > 0) {
|
|
4368
|
+
const task = pickNextSymbolIndexTask();
|
|
4369
|
+
if (task == null) break;
|
|
4370
|
+
pendingSymbolIndexTasks.delete(symbolIndexTaskKey(task.parentPath, task.filePath));
|
|
4371
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
4372
|
+
const latestActiveSequence = latestActiveSequenceByParent.get(task.parentPath);
|
|
4373
|
+
if (latestActiveSequence != null && task.sequence != null && task.sequence < latestActiveSequence) {
|
|
4374
|
+
continue;
|
|
4375
|
+
}
|
|
4376
|
+
if (!await symbolIndexFileIsReadyAsync(task.parentPath, task.filePath)) {
|
|
4377
|
+
try {
|
|
4378
|
+
await ensureSymbolIndexFileImpl(task.parentPath, task.filePath);
|
|
4379
|
+
} catch (err) {
|
|
4380
|
+
if (isSymbolIndexDeferredError(err)) {
|
|
4381
|
+
if (addPendingSymbolIndexTask(task)) kickSymbolIndexWorkerLoop();
|
|
4382
|
+
continue;
|
|
4383
|
+
}
|
|
4384
|
+
throw err;
|
|
4385
|
+
}
|
|
4386
|
+
}
|
|
4387
|
+
}
|
|
4388
|
+
} finally {
|
|
4389
|
+
clearSymbolIndexHeapIfEmpty();
|
|
4390
|
+
setSymbolIndexWorkerRunning(false);
|
|
4391
|
+
if (pendingSymbolIndexTasks.size > 0) void runWorkerLoop();
|
|
4392
|
+
}
|
|
4393
|
+
}
|
|
4394
|
+
function kickSymbolIndexWorkerLoop() {
|
|
4395
|
+
void runWorkerLoop();
|
|
4396
|
+
}
|
|
4397
|
+
var init_task_queue_worker = __esm({
|
|
4398
|
+
"src/code-nav/symbol-index/scheduler/task-queue-worker.ts"() {
|
|
4399
|
+
"use strict";
|
|
4400
|
+
init_deferred_indexing();
|
|
4401
|
+
init_yield_during_work();
|
|
4402
|
+
init_ensure_symbol_index_file_host();
|
|
4403
|
+
init_symbol_index_file_ready();
|
|
4404
|
+
init_task_queue_store();
|
|
4405
|
+
init_task_queue_types();
|
|
4406
|
+
}
|
|
4407
|
+
});
|
|
4408
|
+
|
|
4409
|
+
// src/code-nav/symbol-index/worker/symbol-index-worker-host-queue-handlers.ts
|
|
4410
|
+
function handleQueueWorkerMessage(msg) {
|
|
4411
|
+
switch (msg.type) {
|
|
4412
|
+
case "enqueue":
|
|
4413
|
+
if (enqueueSymbolIndexTaskInternal(msg.parentPath, msg.filePath, msg.priority, msg.sequence)) {
|
|
4414
|
+
kickSymbolIndexWorkerLoop();
|
|
4415
|
+
}
|
|
4416
|
+
return;
|
|
4417
|
+
case "markLatestActive":
|
|
4418
|
+
markLatestActiveSymbolIndexTaskInternal(msg.parentPath, msg.sequence);
|
|
4419
|
+
return;
|
|
4420
|
+
case "deferBackground":
|
|
4421
|
+
deferBackgroundSymbolIndexTasks();
|
|
4422
|
+
return;
|
|
4423
|
+
default:
|
|
4424
|
+
return;
|
|
4425
|
+
}
|
|
4426
|
+
}
|
|
4427
|
+
var init_symbol_index_worker_host_queue_handlers = __esm({
|
|
4428
|
+
"src/code-nav/symbol-index/worker/symbol-index-worker-host-queue-handlers.ts"() {
|
|
4429
|
+
"use strict";
|
|
4430
|
+
init_task_queue_core();
|
|
4431
|
+
init_task_queue_worker();
|
|
4432
|
+
}
|
|
4433
|
+
});
|
|
4434
|
+
|
|
4435
|
+
// src/code-nav/symbol-index/build/register-symbol-index-parent.ts
|
|
4436
|
+
async function registerSymbolIndexParentAsync(parentPath) {
|
|
4437
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
4438
|
+
await withCodeNavCacheSqlite((db) => {
|
|
4439
|
+
upsertSymbolIndexParentPath(db, resolved);
|
|
4440
|
+
});
|
|
4441
|
+
}
|
|
4442
|
+
var init_register_symbol_index_parent = __esm({
|
|
4443
|
+
"src/code-nav/symbol-index/build/register-symbol-index-parent.ts"() {
|
|
4444
|
+
"use strict";
|
|
4445
|
+
init_normalize_resolved_path();
|
|
4446
|
+
init_code_nav_cache_database();
|
|
4447
|
+
init_symbol_index_sqlite();
|
|
4448
|
+
}
|
|
4449
|
+
});
|
|
4450
|
+
|
|
4451
|
+
// src/code-nav/symbol-index/scheduler/symbol-index-warmup-host.ts
|
|
4452
|
+
function scheduleWarmupWhenIdle() {
|
|
4453
|
+
if (warmupIdleTimer != null) clearTimeout(warmupIdleTimer);
|
|
4454
|
+
warmupIdleTimer = setTimeout(() => {
|
|
4455
|
+
warmupIdleTimer = null;
|
|
4456
|
+
if (fileBrowserRequestInFlight()) {
|
|
4457
|
+
scheduleWarmupWhenIdle();
|
|
4458
|
+
return;
|
|
4459
|
+
}
|
|
4460
|
+
for (const parentPath of [...pendingWarmupParents]) {
|
|
4461
|
+
void runWarmupWalk(parentPath);
|
|
4462
|
+
}
|
|
4463
|
+
}, WARMUP_IDLE_MS);
|
|
4464
|
+
}
|
|
4465
|
+
async function runWarmupWalk(resolved) {
|
|
4466
|
+
if (warmupCompleted.has(resolved) || warmupWalkInProgress.has(resolved)) {
|
|
4467
|
+
pendingWarmupParents.delete(resolved);
|
|
4468
|
+
return;
|
|
4469
|
+
}
|
|
4470
|
+
warmupWalkInProgress.add(resolved);
|
|
4471
|
+
pendingWarmupParents.delete(resolved);
|
|
4472
|
+
try {
|
|
4473
|
+
const readyFiles = await loadSymbolIndexReadyFileSet(resolved);
|
|
4474
|
+
const walkState = createWalkYieldState();
|
|
4475
|
+
const yieldState = createCodeNavYieldState();
|
|
4476
|
+
await walkCodeNavFilesAsync(
|
|
4477
|
+
resolved,
|
|
4478
|
+
async (relPath) => {
|
|
4479
|
+
await yieldDuringCodeNavWork(yieldState);
|
|
4480
|
+
if (!readyFiles.has(relPath)) {
|
|
4481
|
+
if (enqueueSymbolIndexTaskInternal(resolved, relPath, ++warmupSeq, requestSeq)) {
|
|
4482
|
+
kickSymbolIndexWorkerLoop();
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4485
|
+
},
|
|
4486
|
+
walkState
|
|
4487
|
+
);
|
|
4488
|
+
warmupCompleted.add(resolved);
|
|
4489
|
+
} finally {
|
|
4490
|
+
warmupWalkInProgress.delete(resolved);
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
function scheduleSymbolIndexWarmupInWorkerHost(parentPath) {
|
|
4494
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
4495
|
+
if (warmupCompleted.has(resolved)) return;
|
|
4496
|
+
pendingWarmupParents.add(resolved);
|
|
4497
|
+
scheduleWarmupWhenIdle();
|
|
4498
|
+
}
|
|
4499
|
+
var requestSeq, warmupSeq, warmupCompleted, pendingWarmupParents, warmupWalkInProgress, WARMUP_IDLE_MS, warmupIdleTimer;
|
|
4500
|
+
var init_symbol_index_warmup_host = __esm({
|
|
4501
|
+
"src/code-nav/symbol-index/scheduler/symbol-index-warmup-host.ts"() {
|
|
4502
|
+
"use strict";
|
|
4503
|
+
init_normalize_resolved_path();
|
|
4504
|
+
init_file_browser_in_flight();
|
|
4505
|
+
init_yield_during_work();
|
|
4506
|
+
init_walk_code_nav_files();
|
|
4507
|
+
init_symbol_index_file_ready();
|
|
4508
|
+
init_task_queue_core();
|
|
4509
|
+
init_task_queue_worker();
|
|
4510
|
+
requestSeq = 0;
|
|
4511
|
+
warmupSeq = 0;
|
|
4512
|
+
warmupCompleted = /* @__PURE__ */ new Set();
|
|
4513
|
+
pendingWarmupParents = /* @__PURE__ */ new Set();
|
|
4514
|
+
warmupWalkInProgress = /* @__PURE__ */ new Set();
|
|
4515
|
+
WARMUP_IDLE_MS = 3e3;
|
|
4516
|
+
warmupIdleTimer = null;
|
|
4517
|
+
registerFileBrowserActivityListener(() => {
|
|
4518
|
+
if (pendingWarmupParents.size > 0) scheduleWarmupWhenIdle();
|
|
4519
|
+
});
|
|
4520
|
+
}
|
|
4521
|
+
});
|
|
4522
|
+
|
|
4523
|
+
// src/code-nav/symbol-index/worker/symbol-index-worker-host-setup-handlers.ts
|
|
4524
|
+
async function handleSetupWorkerMessage(msg) {
|
|
4525
|
+
switch (msg.type) {
|
|
4526
|
+
case "registerParent":
|
|
4527
|
+
await registerSymbolIndexParentAsync(msg.parentPath);
|
|
4528
|
+
return;
|
|
4529
|
+
case "scheduleWarmup":
|
|
4530
|
+
scheduleSymbolIndexWarmupInWorkerHost(msg.parentPath);
|
|
4531
|
+
return;
|
|
4532
|
+
case "shutdown":
|
|
4533
|
+
return;
|
|
4534
|
+
default:
|
|
4535
|
+
return;
|
|
4536
|
+
}
|
|
4537
|
+
}
|
|
4538
|
+
var init_symbol_index_worker_host_setup_handlers = __esm({
|
|
4539
|
+
"src/code-nav/symbol-index/worker/symbol-index-worker-host-setup-handlers.ts"() {
|
|
4540
|
+
"use strict";
|
|
4541
|
+
init_register_symbol_index_parent();
|
|
4542
|
+
init_symbol_index_warmup_host();
|
|
4543
|
+
}
|
|
4544
|
+
});
|
|
4545
|
+
|
|
4546
|
+
// src/code-nav/symbol-index/worker/symbol-index-worker-host-handle-message.ts
|
|
4547
|
+
async function handleRequestMessage(port, msg) {
|
|
4548
|
+
if (isCliImmediateShutdownRequested()) return;
|
|
4549
|
+
switch (msg.type) {
|
|
4550
|
+
case "enqueue":
|
|
4551
|
+
case "markLatestActive":
|
|
4552
|
+
case "deferBackground":
|
|
4553
|
+
handleQueueWorkerMessage(msg);
|
|
4554
|
+
return;
|
|
4555
|
+
case "registerParent":
|
|
4556
|
+
case "scheduleWarmup":
|
|
4557
|
+
case "shutdown":
|
|
4558
|
+
await handleSetupWorkerMessage(msg);
|
|
4559
|
+
return;
|
|
4560
|
+
case "buildFull":
|
|
4561
|
+
case "updateFile":
|
|
4562
|
+
case "removeFile":
|
|
4563
|
+
case "ensureFile":
|
|
4564
|
+
await handleIndexWorkerMessage(port, msg);
|
|
4565
|
+
return;
|
|
4566
|
+
default:
|
|
4567
|
+
return;
|
|
4568
|
+
}
|
|
4569
|
+
}
|
|
4570
|
+
var init_symbol_index_worker_host_handle_message = __esm({
|
|
4571
|
+
"src/code-nav/symbol-index/worker/symbol-index-worker-host-handle-message.ts"() {
|
|
4572
|
+
"use strict";
|
|
4573
|
+
init_cli_process_interrupt();
|
|
4574
|
+
init_symbol_index_worker_host_index_handlers();
|
|
4575
|
+
init_symbol_index_worker_host_queue_handlers();
|
|
4576
|
+
init_symbol_index_worker_host_setup_handlers();
|
|
4577
|
+
}
|
|
4578
|
+
});
|
|
4579
|
+
|
|
4580
|
+
// src/code-nav/symbol-index/worker/symbol-index-worker-host.ts
|
|
4581
|
+
function attachSymbolIndexWorkerHost(port) {
|
|
4582
|
+
port.onMessage((message) => {
|
|
4583
|
+
void handleRequestMessage(port, message);
|
|
4584
|
+
});
|
|
4585
|
+
postSafe(port, { type: "ready" });
|
|
4586
|
+
}
|
|
4587
|
+
var init_symbol_index_worker_host = __esm({
|
|
4588
|
+
"src/code-nav/symbol-index/worker/symbol-index-worker-host.ts"() {
|
|
4589
|
+
"use strict";
|
|
4590
|
+
init_symbol_index_worker_host_handle_message();
|
|
4591
|
+
init_symbol_index_worker_host_post();
|
|
4592
|
+
}
|
|
4593
|
+
});
|
|
4594
|
+
|
|
4595
|
+
// src/code-nav/symbol-index/worker/symbol-index-worker.ts
|
|
4596
|
+
init_symbol_index_worker_host();
|
|
4597
|
+
import { parentPort } from "node:worker_threads";
|
|
4598
|
+
if (parentPort == null) {
|
|
4599
|
+
throw new Error("symbol-index-worker must run as a worker thread");
|
|
4600
|
+
}
|
|
4601
|
+
attachSymbolIndexWorkerHost({
|
|
4602
|
+
postMessage(message) {
|
|
4603
|
+
parentPort.postMessage(message);
|
|
4604
|
+
},
|
|
4605
|
+
onMessage(handler) {
|
|
4606
|
+
parentPort.on("message", handler);
|
|
4607
|
+
}
|
|
4608
|
+
});
|
|
4609
|
+
//# sourceMappingURL=symbol-index-worker.js.map
|