gitnexus 1.6.6-rc.1 → 1.6.6-rc.3
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/_shared/index.d.ts +1 -1
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +13 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
- package/dist/cli/analyze.js +11 -0
- package/dist/cli/serve.js +6 -1
- package/dist/core/ingestion/languages/cpp/arity-metadata.d.ts +9 -0
- package/dist/core/ingestion/languages/cpp/arity-metadata.js +50 -1
- package/dist/core/ingestion/languages/cpp/captures.js +3 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +2 -1
- package/dist/core/ingestion/model/symbol-table.js +3 -0
- package/dist/core/ingestion/parsing-processor.js +2 -0
- package/dist/core/ingestion/scope-extractor.js +46 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +2 -1
- package/dist/core/ingestion/workers/parse-worker.js +1 -0
- package/dist/core/lbug/lbug-adapter.js +17 -1
- package/dist/core/lbug/lbug-config.d.ts +1 -1
- package/dist/core/lbug/lbug-config.js +1 -1
- package/dist/core/lbug/pool-adapter.js +2 -3
- package/package.json +1 -1
package/dist/_shared/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { SupportedLanguages } from './languages.js';
|
|
|
5
5
|
export { getLanguageFromFilename, getSyntaxLanguageFromFilename } from './language-detection.js';
|
|
6
6
|
export type { MroStrategy } from './mro-strategy.js';
|
|
7
7
|
export type { PipelinePhase, PipelineProgress } from './pipeline.js';
|
|
8
|
-
export type { SymbolDefinition } from './scope-resolution/symbol-definition.js';
|
|
8
|
+
export type { ParameterTypeClass, SymbolDefinition } from './scope-resolution/symbol-definition.js';
|
|
9
9
|
export type { ScopeId, DefId, ScopeKind, Range, Capture, CaptureMatch, BindingRef, ImportEdge, TypeRef, Scope, ResolutionEvidence, Resolution, Reference, ReferenceIndex, LookupParams, RegistryContributor, ParsedImport, ParsedTypeBinding, WorkspaceIndex, Callsite, ScopeLookup, } from './scope-resolution/types.js';
|
|
10
10
|
export { EvidenceWeights, typeBindingWeightAtDepth } from './scope-resolution/evidence-weights.js';
|
|
11
11
|
export { ORIGIN_PRIORITY } from './scope-resolution/origin-priority.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIrE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,16 @@
|
|
|
9
9
|
* Shape is unchanged from the prior local definition.
|
|
10
10
|
*/
|
|
11
11
|
import type { NodeLabel } from '../graph/types.js';
|
|
12
|
+
export interface ParameterTypeClass {
|
|
13
|
+
/** Normalized base type, matching the coarse `parameterTypes` vocabulary when known. */
|
|
14
|
+
base: string;
|
|
15
|
+
/** Top-level cv signal preserved from the original C++ parameter spelling. */
|
|
16
|
+
cv: 'none' | 'const' | 'volatile' | 'const volatile' | 'unknown';
|
|
17
|
+
/** Coarse value/reference/pointer shape. */
|
|
18
|
+
indirection: 'value' | 'lvalue-ref' | 'rvalue-ref' | 'pointer' | 'unknown';
|
|
19
|
+
/** Number of pointer markers when indirection is `pointer`; otherwise 0. */
|
|
20
|
+
pointerDepth: number;
|
|
21
|
+
}
|
|
12
22
|
export interface SymbolDefinition {
|
|
13
23
|
nodeId: string;
|
|
14
24
|
filePath: string;
|
|
@@ -24,6 +34,9 @@ export interface SymbolDefinition {
|
|
|
24
34
|
/** Per-parameter type names for overload disambiguation (e.g. ['int', 'String']).
|
|
25
35
|
* Populated when parameter types are resolvable from AST (any typed language). */
|
|
26
36
|
parameterTypes?: string[];
|
|
37
|
+
/** Additive per-parameter type shape sidecar for languages that need cv/ref/pointer distinctions.
|
|
38
|
+
* Does not participate in graph node identity unless a resolver explicitly opts in. */
|
|
39
|
+
parameterTypeClasses?: ParameterTypeClass[];
|
|
27
40
|
/** Raw return type text extracted from AST (e.g. 'User', 'Promise<User>') */
|
|
28
41
|
returnType?: string;
|
|
29
42
|
/** Declared type for non-callable symbols — fields/properties (e.g. 'Address', 'List<User>') */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbol-definition.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/symbol-definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB;;+FAE2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;iHAC6G;IAC7G,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;uFACmF;IACnF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;yEAKqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
|
1
|
+
{"version":3,"file":"symbol-definition.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/symbol-definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACjE,4CAA4C;IAC5C,WAAW,EAAE,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3E,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB;;+FAE2F;IAC3F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;iHAC6G;IAC7G,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;uFACmF;IACnF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;4FACwF;IACxF,oBAAoB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC5C,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gGAAgG;IAChG,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B;;;;;yEAKqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
package/dist/cli/analyze.js
CHANGED
|
@@ -12,6 +12,7 @@ import { execFileSync } from 'child_process';
|
|
|
12
12
|
import v8 from 'v8';
|
|
13
13
|
import cliProgress from 'cli-progress';
|
|
14
14
|
import { closeLbug } from '../core/lbug/lbug-adapter.js';
|
|
15
|
+
import { isWalCorruptionError, WAL_RECOVERY_SUGGESTION } from '../core/lbug/lbug-config.js';
|
|
15
16
|
import { getStoragePaths, getGlobalRegistryPath, RegistryNameCollisionError, AnalysisNotFinalizedError, assertAnalysisFinalized, } from '../storage/repo-manager.js';
|
|
16
17
|
import { getGitRoot, hasGitDir } from '../storage/git.js';
|
|
17
18
|
import { runFullAnalysis } from '../core/run-analyze.js';
|
|
@@ -468,6 +469,16 @@ export const analyzeCommand = async (inputPath, options) => {
|
|
|
468
469
|
process.exitCode = 1;
|
|
469
470
|
return;
|
|
470
471
|
}
|
|
472
|
+
// WAL corruption — the index file is unreadable. Give a clear recovery
|
|
473
|
+
// path without a confusing stack trace (the native error message alone
|
|
474
|
+
// is enough signal).
|
|
475
|
+
if (isWalCorruptionError(err) || msg.includes('LadybugDB WAL corruption')) {
|
|
476
|
+
cliError(` The GitNexus index has a corrupted WAL file.\n` +
|
|
477
|
+
` This usually happens when a previous analysis was interrupted mid-write.\n` +
|
|
478
|
+
` ${WAL_RECOVERY_SUGGESTION}\n`, { recoveryHint: 'wal-corruption' });
|
|
479
|
+
process.exitCode = 1;
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
471
482
|
// HF download failure — show clean guidance without the raw stack trace.
|
|
472
483
|
// Checked before writeFatalToStderr so the user sees one focused message
|
|
473
484
|
// rather than a stack-trace dump followed by a second remediation block.
|
package/dist/cli/serve.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createServer } from '../server/api.js';
|
|
2
2
|
import { logger, flushLoggerSync } from '../core/logger.js';
|
|
3
3
|
import { cliError } from './cli-message.js';
|
|
4
|
+
import { isWalCorruptionError, WAL_RECOVERY_SUGGESTION } from '../core/lbug/lbug-config.js';
|
|
4
5
|
// Catch anything that would cause a silent exit. Pino v10's default
|
|
5
6
|
// destination is `sync: false` (SonicBoom buffered) — call
|
|
6
7
|
// `flushLoggerSync()` between the log and `process.exit(1)` so the crash
|
|
@@ -32,7 +33,11 @@ export const serveCommand = async (options) => {
|
|
|
32
33
|
await createServer(port, host);
|
|
33
34
|
}
|
|
34
35
|
catch (err) {
|
|
35
|
-
if (err
|
|
36
|
+
if (isWalCorruptionError(err)) {
|
|
37
|
+
cliError(`\nGitNexus server could not start: the index has a corrupted WAL file.\n` +
|
|
38
|
+
` ${WAL_RECOVERY_SUGGESTION}\n`, { recoveryHint: 'wal-corruption' });
|
|
39
|
+
}
|
|
40
|
+
else if (err.code === 'EADDRINUSE') {
|
|
36
41
|
cliError(`\nFailed to start GitNexus server:\n` +
|
|
37
42
|
` ${err.message || err}\n\n` +
|
|
38
43
|
` Port ${port} is already in use. Either:\n` +
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { SyntaxNode } from '../../utils/ast-helpers.js';
|
|
2
|
+
import type { ParameterTypeClass } from '../../../../_shared/index.js';
|
|
2
3
|
export interface CppArityInfo {
|
|
3
4
|
parameterCount?: number;
|
|
4
5
|
requiredParameterCount?: number;
|
|
5
6
|
parameterTypes?: string[];
|
|
7
|
+
parameterTypeClasses?: ParameterTypeClass[];
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
10
|
* Compute declaration arity from a C++ function definition or declaration node.
|
|
@@ -22,5 +24,12 @@ export declare function computeCppCallArity(node: SyntaxNode): number;
|
|
|
22
24
|
* so that `narrowOverloadCandidates` can match against literal-inferred
|
|
23
25
|
* argument types (e.g. `inferCppLiteralType` returns `'string'` for
|
|
24
26
|
* string literals, not `'std::string'`).
|
|
27
|
+
*
|
|
28
|
+
* This intentionally remains coarse and graph-ID-stable: cv-qualifiers,
|
|
29
|
+
* reference markers, and pointer markers are stripped here. C++ callers
|
|
30
|
+
* that need those distinctions should read `parameterTypeClasses`, which
|
|
31
|
+
* is an additive sidecar and does not participate in overload node ID
|
|
32
|
+
* hashing.
|
|
25
33
|
*/
|
|
26
34
|
export declare function normalizeCppParamType(raw: string): string;
|
|
35
|
+
export declare function classifyCppParameterType(rawType: string, declaratorText?: string, fullParameterText?: string): ParameterTypeClass;
|
|
@@ -55,27 +55,34 @@ export function computeCppDeclarationArity(node) {
|
|
|
55
55
|
p.type === 'variadic_parameter_declaration').length;
|
|
56
56
|
const totalNonVariadic = requiredCount + optionalCount;
|
|
57
57
|
const types = [];
|
|
58
|
+
const typeClasses = [];
|
|
58
59
|
for (const p of params) {
|
|
59
60
|
if (p.type === 'variadic_parameter') {
|
|
60
61
|
types.push('...');
|
|
62
|
+
typeClasses.push(unknownTypeClass('...'));
|
|
61
63
|
}
|
|
62
64
|
else if (p.type === 'variadic_parameter_declaration') {
|
|
63
65
|
// Parameter pack: treated as variadic
|
|
64
66
|
types.push('...');
|
|
67
|
+
typeClasses.push(unknownTypeClass('...'));
|
|
65
68
|
}
|
|
66
69
|
else {
|
|
67
70
|
const typeNode = p.childForFieldName('type');
|
|
68
|
-
|
|
71
|
+
const rawType = typeNode?.text ?? 'unknown';
|
|
72
|
+
types.push(normalizeCppParamType(rawType));
|
|
73
|
+
typeClasses.push(classifyCppParameterType(rawType, p.childForFieldName('declarator')?.text, p.text));
|
|
69
74
|
}
|
|
70
75
|
}
|
|
71
76
|
// Append '...' for C-style variadic if not already in types
|
|
72
77
|
if (hasEllipsis && !types.includes('...')) {
|
|
73
78
|
types.push('...');
|
|
79
|
+
typeClasses.push(unknownTypeClass('...'));
|
|
74
80
|
}
|
|
75
81
|
return {
|
|
76
82
|
parameterCount: isVariadic ? undefined : totalNonVariadic,
|
|
77
83
|
requiredParameterCount: requiredCount,
|
|
78
84
|
parameterTypes: types,
|
|
85
|
+
parameterTypeClasses: typeClasses,
|
|
79
86
|
};
|
|
80
87
|
}
|
|
81
88
|
/**
|
|
@@ -102,6 +109,12 @@ export function computeCppCallArity(node) {
|
|
|
102
109
|
* so that `narrowOverloadCandidates` can match against literal-inferred
|
|
103
110
|
* argument types (e.g. `inferCppLiteralType` returns `'string'` for
|
|
104
111
|
* string literals, not `'std::string'`).
|
|
112
|
+
*
|
|
113
|
+
* This intentionally remains coarse and graph-ID-stable: cv-qualifiers,
|
|
114
|
+
* reference markers, and pointer markers are stripped here. C++ callers
|
|
115
|
+
* that need those distinctions should read `parameterTypeClasses`, which
|
|
116
|
+
* is an additive sidecar and does not participate in overload node ID
|
|
117
|
+
* hashing.
|
|
105
118
|
*/
|
|
106
119
|
export function normalizeCppParamType(raw) {
|
|
107
120
|
let t = raw.trim();
|
|
@@ -140,6 +153,42 @@ export function normalizeCppParamType(raw) {
|
|
|
140
153
|
};
|
|
141
154
|
return STD_MAP[t] ?? t;
|
|
142
155
|
}
|
|
156
|
+
export function classifyCppParameterType(rawType, declaratorText, fullParameterText) {
|
|
157
|
+
const source = fullParameterText ?? `${rawType} ${declaratorText ?? ''}`.trim();
|
|
158
|
+
if (rawType === 'unknown')
|
|
159
|
+
return unknownTypeClass('unknown');
|
|
160
|
+
const hasConst = /\bconst\b/.test(source);
|
|
161
|
+
const hasVolatile = /\bvolatile\b/.test(source);
|
|
162
|
+
const cv = hasConst && hasVolatile
|
|
163
|
+
? 'const volatile'
|
|
164
|
+
: hasConst
|
|
165
|
+
? 'const'
|
|
166
|
+
: hasVolatile
|
|
167
|
+
? 'volatile'
|
|
168
|
+
: 'none';
|
|
169
|
+
const pointerDepth = (source.match(/\*/g) ?? []).length;
|
|
170
|
+
const indirection = pointerDepth > 0
|
|
171
|
+
? 'pointer'
|
|
172
|
+
: /&&/.test(source)
|
|
173
|
+
? 'rvalue-ref'
|
|
174
|
+
: /&/.test(source)
|
|
175
|
+
? 'lvalue-ref'
|
|
176
|
+
: 'value';
|
|
177
|
+
return {
|
|
178
|
+
base: normalizeCppParamType(rawType),
|
|
179
|
+
cv,
|
|
180
|
+
indirection,
|
|
181
|
+
pointerDepth,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function unknownTypeClass(base) {
|
|
185
|
+
return {
|
|
186
|
+
base,
|
|
187
|
+
cv: 'unknown',
|
|
188
|
+
indirection: 'unknown',
|
|
189
|
+
pointerDepth: 0,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
143
192
|
function findFuncDeclarator(node) {
|
|
144
193
|
let decl = node.childForFieldName('declarator');
|
|
145
194
|
if (decl === null) {
|
|
@@ -86,6 +86,9 @@ export function emitCppScopeCaptures(sourceText, filePath, cachedTree) {
|
|
|
86
86
|
if (arity.parameterTypes !== undefined) {
|
|
87
87
|
grouped['@declaration.parameter-types'] = syntheticCapture('@declaration.parameter-types', fnNode, JSON.stringify(arity.parameterTypes));
|
|
88
88
|
}
|
|
89
|
+
if (arity.parameterTypeClasses !== undefined) {
|
|
90
|
+
grouped['@declaration.parameter-type-classes'] = syntheticCapture('@declaration.parameter-type-classes', fnNode, JSON.stringify(arity.parameterTypeClasses));
|
|
91
|
+
}
|
|
89
92
|
// Detect static storage class (file-local linkage)
|
|
90
93
|
if (hasStaticStorageClass(fnNode)) {
|
|
91
94
|
const nameText = grouped['@declaration.name']?.text;
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
* import from `./model/` here, you are going the wrong way — move the
|
|
34
34
|
* logic up the dependency chain instead.
|
|
35
35
|
*/
|
|
36
|
-
import type { NodeLabel, SymbolDefinition } from '../../../_shared/index.js';
|
|
36
|
+
import type { NodeLabel, ParameterTypeClass, SymbolDefinition } from '../../../_shared/index.js';
|
|
37
37
|
/**
|
|
38
38
|
* Class-like NodeLabels — used for qualifiedName fallback inside
|
|
39
39
|
* `SymbolTable.add()` and (via import into `model/registration-table.ts`)
|
|
@@ -97,6 +97,7 @@ export interface AddMetadata {
|
|
|
97
97
|
parameterCount?: number;
|
|
98
98
|
requiredParameterCount?: number;
|
|
99
99
|
parameterTypes?: string[];
|
|
100
|
+
parameterTypeClasses?: ParameterTypeClass[];
|
|
100
101
|
returnType?: string;
|
|
101
102
|
declaredType?: string;
|
|
102
103
|
templateArguments?: string[];
|
|
@@ -128,6 +128,9 @@ export const createSymbolTable = () => {
|
|
|
128
128
|
...(metadata?.parameterTypes !== undefined
|
|
129
129
|
? { parameterTypes: metadata.parameterTypes }
|
|
130
130
|
: {}),
|
|
131
|
+
...(metadata?.parameterTypeClasses !== undefined
|
|
132
|
+
? { parameterTypeClasses: metadata.parameterTypeClasses }
|
|
133
|
+
: {}),
|
|
131
134
|
...(metadata?.returnType !== undefined ? { returnType: metadata.returnType } : {}),
|
|
132
135
|
...(metadata?.declaredType !== undefined ? { declaredType: metadata.declaredType } : {}),
|
|
133
136
|
...(metadata?.templateArguments !== undefined
|
|
@@ -57,6 +57,7 @@ export const mergeChunkResults = (graph, symbolTable, chunkResults) => {
|
|
|
57
57
|
parameterCount: sym.parameterCount,
|
|
58
58
|
requiredParameterCount: sym.requiredParameterCount,
|
|
59
59
|
parameterTypes: sym.parameterTypes,
|
|
60
|
+
parameterTypeClasses: sym.parameterTypeClasses,
|
|
60
61
|
returnType: sym.returnType,
|
|
61
62
|
declaredType: sym.declaredType,
|
|
62
63
|
templateArguments: sym.templateArguments,
|
|
@@ -610,6 +611,7 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, sco
|
|
|
610
611
|
parameterCount: methodProps.parameterCount,
|
|
611
612
|
requiredParameterCount: methodProps.requiredParameterCount,
|
|
612
613
|
parameterTypes: methodProps.parameterTypes,
|
|
614
|
+
parameterTypeClasses: methodProps.parameterTypeClasses,
|
|
613
615
|
returnType: methodProps.returnType,
|
|
614
616
|
declaredType,
|
|
615
617
|
templateArguments: classTemplateArguments,
|
|
@@ -372,6 +372,7 @@ function buildDefFromDeclarationMatch(match, anchor, filePath) {
|
|
|
372
372
|
const parameterCount = parseIntCapture(match['@declaration.parameter-count']);
|
|
373
373
|
const requiredParameterCount = parseIntCapture(match['@declaration.required-parameter-count']);
|
|
374
374
|
const parameterTypes = parseJsonStringArrayCapture(match['@declaration.parameter-types']);
|
|
375
|
+
const parameterTypeClasses = parseJsonParameterTypeClassesCapture(match['@declaration.parameter-type-classes']);
|
|
375
376
|
const declaredType = match['@declaration.field-type']?.text;
|
|
376
377
|
const returnType = match['@declaration.return-type']?.text;
|
|
377
378
|
const templateConstraints = parseJsonCapture(match['@declaration.template-constraints']);
|
|
@@ -383,6 +384,7 @@ function buildDefFromDeclarationMatch(match, anchor, filePath) {
|
|
|
383
384
|
...(parameterCount !== undefined ? { parameterCount } : {}),
|
|
384
385
|
...(requiredParameterCount !== undefined ? { requiredParameterCount } : {}),
|
|
385
386
|
...(parameterTypes !== undefined ? { parameterTypes } : {}),
|
|
387
|
+
...(parameterTypeClasses !== undefined ? { parameterTypeClasses } : {}),
|
|
386
388
|
...(declaredType !== undefined ? { declaredType } : {}),
|
|
387
389
|
...(returnType !== undefined ? { returnType } : {}),
|
|
388
390
|
...(templateArguments !== undefined ? { templateArguments } : {}),
|
|
@@ -409,6 +411,50 @@ function parseIntCapture(cap) {
|
|
|
409
411
|
const n = Number.parseInt(cap.text, 10);
|
|
410
412
|
return Number.isFinite(n) ? n : undefined;
|
|
411
413
|
}
|
|
414
|
+
function parseJsonParameterTypeClassesCapture(cap) {
|
|
415
|
+
if (cap === undefined)
|
|
416
|
+
return undefined;
|
|
417
|
+
try {
|
|
418
|
+
const parsed = JSON.parse(cap.text);
|
|
419
|
+
if (!Array.isArray(parsed))
|
|
420
|
+
return undefined;
|
|
421
|
+
const out = [];
|
|
422
|
+
for (const item of parsed) {
|
|
423
|
+
if (item === null || typeof item !== 'object')
|
|
424
|
+
return undefined;
|
|
425
|
+
const o = item;
|
|
426
|
+
if (typeof o.base !== 'string')
|
|
427
|
+
return undefined;
|
|
428
|
+
if (o.cv !== 'none' &&
|
|
429
|
+
o.cv !== 'const' &&
|
|
430
|
+
o.cv !== 'volatile' &&
|
|
431
|
+
o.cv !== 'const volatile' &&
|
|
432
|
+
o.cv !== 'unknown') {
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
if (o.indirection !== 'value' &&
|
|
436
|
+
o.indirection !== 'lvalue-ref' &&
|
|
437
|
+
o.indirection !== 'rvalue-ref' &&
|
|
438
|
+
o.indirection !== 'pointer' &&
|
|
439
|
+
o.indirection !== 'unknown') {
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
if (typeof o.pointerDepth !== 'number' || !Number.isFinite(o.pointerDepth)) {
|
|
443
|
+
return undefined;
|
|
444
|
+
}
|
|
445
|
+
out.push({
|
|
446
|
+
base: o.base,
|
|
447
|
+
cv: o.cv,
|
|
448
|
+
indirection: o.indirection,
|
|
449
|
+
pointerDepth: o.pointerDepth,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
return out;
|
|
453
|
+
}
|
|
454
|
+
catch {
|
|
455
|
+
return undefined;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
412
458
|
function parseJsonStringArrayCapture(cap) {
|
|
413
459
|
if (cap === undefined)
|
|
414
460
|
return undefined;
|
|
@@ -3,7 +3,7 @@ import type { ExtractedHeritage } from '../model/heritage-map.js';
|
|
|
3
3
|
import { type MixedChainStep } from '../utils/call-analysis.js';
|
|
4
4
|
import type { ConstructorBinding } from '../type-env.js';
|
|
5
5
|
import type { NamedBinding } from '../named-bindings/types.js';
|
|
6
|
-
import type { NodeLabel } from '../../../_shared/index.js';
|
|
6
|
+
import type { NodeLabel, ParameterTypeClass } from '../../../_shared/index.js';
|
|
7
7
|
import type { ParsedFile } from '../../../_shared/index.js';
|
|
8
8
|
interface ParsedNode {
|
|
9
9
|
id: string;
|
|
@@ -38,6 +38,7 @@ interface ParsedSymbol {
|
|
|
38
38
|
parameterCount?: number;
|
|
39
39
|
requiredParameterCount?: number;
|
|
40
40
|
parameterTypes?: string[];
|
|
41
|
+
parameterTypeClasses?: ParameterTypeClass[];
|
|
41
42
|
returnType?: string;
|
|
42
43
|
declaredType?: string;
|
|
43
44
|
templateArguments?: string[];
|
|
@@ -1801,6 +1801,7 @@ const processFileGroup = (files, language, queryString, result, onFileProcessed)
|
|
|
1801
1801
|
parameterCount: methodProps.parameterCount,
|
|
1802
1802
|
requiredParameterCount: methodProps.requiredParameterCount,
|
|
1803
1803
|
parameterTypes: methodProps.parameterTypes,
|
|
1804
|
+
parameterTypeClasses: methodProps.parameterTypeClasses,
|
|
1804
1805
|
returnType: methodProps.returnType,
|
|
1805
1806
|
...(declaredType !== undefined ? { declaredType } : {}),
|
|
1806
1807
|
...(classTemplateArguments !== undefined && classTemplateArguments.length > 0
|
|
@@ -8,7 +8,7 @@ import lbug from '@ladybugdb/core';
|
|
|
8
8
|
import { NODE_TABLES, REL_TABLE_NAME, SCHEMA_QUERIES, EMBEDDING_TABLE_NAME, STALE_HASH_SENTINEL, } from './schema.js';
|
|
9
9
|
import { streamAllCSVsToDisk } from './csv-generator.js';
|
|
10
10
|
import { extensionManager } from './extension-loader.js';
|
|
11
|
-
import { closeLbugConnection, isDbBusyError, isOpenRetryExhausted, openLbugConnection, waitForWindowsHandleRelease, } from './lbug-config.js';
|
|
11
|
+
import { closeLbugConnection, isDbBusyError, isOpenRetryExhausted, isWalCorruptionError, openLbugConnection, WAL_RECOVERY_SUGGESTION, waitForWindowsHandleRelease, } from './lbug-config.js';
|
|
12
12
|
import { isVectorExtensionSupportedByPlatform } from '../platform/capabilities.js';
|
|
13
13
|
import { logger } from '../logger.js';
|
|
14
14
|
/**
|
|
@@ -508,6 +508,22 @@ const doInitLbug = async (dbPath) => {
|
|
|
508
508
|
// anyway and any genuine cross-process lock contention surfaces
|
|
509
509
|
// on the next operation via withLbugDb's retry. Logging it here
|
|
510
510
|
// would just be noise in CI.
|
|
511
|
+
//
|
|
512
|
+
// WAL corruption: the first DDL write after DB open triggers WAL
|
|
513
|
+
// replay — if the WAL file was left in a corrupt state by an
|
|
514
|
+
// interrupted previous run, the native engine throws here. Rather
|
|
515
|
+
// than logging a WARN and continuing in a broken state, close the
|
|
516
|
+
// DB cleanly and surface an actionable error so the caller (serve,
|
|
517
|
+
// MCP, analyze) can exit with a clear recovery message.
|
|
518
|
+
if (isWalCorruptionError(err)) {
|
|
519
|
+
await safeClose();
|
|
520
|
+
currentDbPath = null;
|
|
521
|
+
ftsLoaded = false;
|
|
522
|
+
vectorExtensionLoaded = false;
|
|
523
|
+
ensuredFTSIndexes.clear();
|
|
524
|
+
throw new Error(`LadybugDB WAL corruption detected at ${dbPath}. ${WAL_RECOVERY_SUGGESTION}\n` +
|
|
525
|
+
` Original error: ${msg.slice(0, 200)}`);
|
|
526
|
+
}
|
|
511
527
|
if (!msg.includes('already exists') && !isDbBusyError(err)) {
|
|
512
528
|
logger.warn(`⚠️ Schema creation warning: ${msg.slice(0, 120)}`);
|
|
513
529
|
}
|
|
@@ -32,7 +32,7 @@ import type lbug from '@ladybugdb/core';
|
|
|
32
32
|
* integer; anything invalid falls back to the default.
|
|
33
33
|
*/
|
|
34
34
|
export declare const LBUG_MAX_DB_SIZE: number;
|
|
35
|
-
export declare const WAL_RECOVERY_SUGGESTION = "WAL corruption detected. Run `gitnexus analyze` to rebuild the index.";
|
|
35
|
+
export declare const WAL_RECOVERY_SUGGESTION = "WAL corruption detected. Run `gitnexus analyze --force` to rebuild the index.";
|
|
36
36
|
export declare function isWalCorruptionError(err: unknown): boolean;
|
|
37
37
|
type LbugModule = typeof lbug;
|
|
38
38
|
export interface LbugDatabaseOptions {
|
|
@@ -44,7 +44,7 @@ export const LBUG_MAX_DB_SIZE = (() => {
|
|
|
44
44
|
})();
|
|
45
45
|
/** Matches WAL corruption errors from the LadybugDB engine. */
|
|
46
46
|
const WAL_CORRUPTION_RE = /corrupt(ed)?\s+wal|invalid\s+wal\s+record|wal.*corrupt|checksum.*wal/i;
|
|
47
|
-
export const WAL_RECOVERY_SUGGESTION = 'WAL corruption detected. Run `gitnexus analyze` to rebuild the index.';
|
|
47
|
+
export const WAL_RECOVERY_SUGGESTION = 'WAL corruption detected. Run `gitnexus analyze --force` to rebuild the index.';
|
|
48
48
|
export function isWalCorruptionError(err) {
|
|
49
49
|
if (!err)
|
|
50
50
|
return false;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import fs from 'fs/promises';
|
|
18
18
|
import lbug from '@ladybugdb/core';
|
|
19
19
|
import { loadFTSExtension } from './lbug-adapter.js';
|
|
20
|
-
import { createLbugDatabase, isWalCorruptionError } from './lbug-config.js';
|
|
20
|
+
import { createLbugDatabase, isWalCorruptionError, WAL_RECOVERY_SUGGESTION, } from './lbug-config.js';
|
|
21
21
|
const pool = new Map();
|
|
22
22
|
const poolCloseListeners = new Set();
|
|
23
23
|
/**
|
|
@@ -310,8 +310,7 @@ async function doInitLbug(repoId, dbPath) {
|
|
|
310
310
|
break;
|
|
311
311
|
}
|
|
312
312
|
catch (retryErr) {
|
|
313
|
-
throw new Error(`LadybugDB WAL corruption detected for ${repoId}. ` +
|
|
314
|
-
`Run \`gitnexus analyze\` to rebuild the index. ` +
|
|
313
|
+
throw new Error(`LadybugDB WAL corruption detected for ${repoId}. ${WAL_RECOVERY_SUGGESTION} ` +
|
|
315
314
|
`(${retryErr instanceof Error ? retryErr.message : String(retryErr)})`);
|
|
316
315
|
}
|
|
317
316
|
}
|
package/package.json
CHANGED