@colbymchenry/codegraph 1.1.6 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +17 -0
- package/dist/extraction/tree-sitter-types.d.ts +17 -0
- package/dist/resolution/callback-synthesizer.d.ts +1 -1
- package/dist/resolution/cooperative-yield.d.ts +32 -0
- package/dist/resolution/index.d.ts +11 -2
- package/dist/resolution/name-matcher.d.ts +22 -0
- package/npm-shim.js +2 -2
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -47,5 +47,22 @@ export declare const cExtractor: LanguageExtractor;
|
|
|
47
47
|
* so C's heavier use of `struct TAG var;` never reaches it.
|
|
48
48
|
*/
|
|
49
49
|
export declare function blankCppExportMacros(source: string): string;
|
|
50
|
+
export declare function blankCppInlineMacros(source: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* Universal fallback (any macro, no list) for a C/C++ function name still mangled
|
|
53
|
+
* because a macro we don't blank sat in front of the return type: `MACRO Ret
|
|
54
|
+
* name(…)` / `Ret MACRO name(…)` misparse so the return type is glued onto the
|
|
55
|
+
* name ("Ret name", "char_t* to_str(double v)"). Recover the real identifier —
|
|
56
|
+
* the token immediately before the parameter list (or the last token). This runs
|
|
57
|
+
* AFTER the curated pre-parse blank, so it only ever sees the residual tail that
|
|
58
|
+
* blanking didn't already fix cleanly (which also recovers the return type).
|
|
59
|
+
*
|
|
60
|
+
* Safe by construction: only touches an ALREADY-mangled name — one with an
|
|
61
|
+
* internal space that isn't a legit `operator …`/destructor — so a well-formed
|
|
62
|
+
* name is returned unchanged. Guarded against the two ways it could mis-pick:
|
|
63
|
+
* the `Ret (name)` parenthesized-name idiom (left as-is, ambiguous), and a token
|
|
64
|
+
* that is a bare primitive/keyword rather than a real identifier.
|
|
65
|
+
*/
|
|
66
|
+
export declare function recoverMangledCppName(name: string): string;
|
|
50
67
|
export declare const cppExtractor: LanguageExtractor;
|
|
51
68
|
//# sourceMappingURL=c-cpp.d.ts.map
|
|
@@ -114,6 +114,15 @@ export interface LanguageExtractor {
|
|
|
114
114
|
returnField?: string;
|
|
115
115
|
/** Override symbol name extraction (e.g. ObjC multi-part selectors). */
|
|
116
116
|
resolveName?: (node: SyntaxNode, source: string) => string | undefined;
|
|
117
|
+
/**
|
|
118
|
+
* Post-process an already-extracted name to recover a real identifier from a
|
|
119
|
+
* name still mangled by a macro the pre-parse didn't blank (C/C++:
|
|
120
|
+
* `MACRO Ret name(` misparses to the name "Ret name"). Applied to every name
|
|
121
|
+
* this extractor produces, so it MUST be a no-op on a well-formed name — only
|
|
122
|
+
* C/C++ set it, because a mangled name there is unambiguous (an internal space),
|
|
123
|
+
* whereas e.g. Kotlin/Scala backtick identifiers legitimately contain spaces.
|
|
124
|
+
*/
|
|
125
|
+
recoverMangledName?: (name: string) => string;
|
|
117
126
|
/** Extract property name when the generic name walk fails (e.g. ObjC @property). */
|
|
118
127
|
extractPropertyName?: (node: SyntaxNode, source: string) => string | null;
|
|
119
128
|
/** Extract signature from node */
|
|
@@ -140,6 +149,14 @@ export interface LanguageExtractor {
|
|
|
140
149
|
extraClassNodeTypes?: string[];
|
|
141
150
|
/** Whether methods can be top-level without enclosing class (Go: true) */
|
|
142
151
|
methodsAreTopLevel?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Skip a bodiless class node as a forward declaration / elaborated type,
|
|
154
|
+
* mirroring the bodiless-struct/enum skip. Set only for languages where a
|
|
155
|
+
* bodiless `class` specifier is NOT a complete definition — C/C++
|
|
156
|
+
* (`class Foo;` is a forward decl). Leave unset for languages where a
|
|
157
|
+
* bodiless class IS complete (Kotlin `class Empty`, Scala `case object`). (#1093)
|
|
158
|
+
*/
|
|
159
|
+
skipBodilessClass?: boolean;
|
|
143
160
|
/** NodeKind to use for interface-like declarations (Rust: 'trait'). Default: 'interface' */
|
|
144
161
|
interfaceKind?: NodeKind;
|
|
145
162
|
/**
|
|
@@ -11,5 +11,5 @@ import type { ResolutionContext } from './types';
|
|
|
11
11
|
* Sidekiq Worker.perform_async → #perform + Laravel event(new X) → listener handle).
|
|
12
12
|
* Returns the count added. Never throws into indexing — callers wrap in try/catch.
|
|
13
13
|
*/
|
|
14
|
-
export declare function synthesizeCallbackEdges(queries: QueryBuilder, ctx: ResolutionContext): number
|
|
14
|
+
export declare function synthesizeCallbackEdges(queries: QueryBuilder, ctx: ResolutionContext): Promise<number>;
|
|
15
15
|
//# sourceMappingURL=callback-synthesizer.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cooperative yielding for long synchronous resolution spans.
|
|
3
|
+
*
|
|
4
|
+
* Reference resolution and callback-edge synthesis run on the indexer's MAIN
|
|
5
|
+
* thread — unlike parsing, which is off-thread in the parse worker. The #850
|
|
6
|
+
* liveness watchdog (armed on `index`/`init` since #999) SIGKILLs the process
|
|
7
|
+
* when that thread doesn't turn its event loop for the timeout window (default
|
|
8
|
+
* 60s), because its heartbeat is a `setInterval` on that same thread. On a large
|
|
9
|
+
* repo, resolving refs + synthesizing dynamic-dispatch edges legitimately runs
|
|
10
|
+
* for minutes, so a span that never yields starves the heartbeat and the
|
|
11
|
+
* watchdog kills a VALID, in-progress index — the exact symptom of #1091 (the
|
|
12
|
+
* progress bar freezes at wherever it last rendered — 88% / 100% — then the
|
|
13
|
+
* process is killed).
|
|
14
|
+
*
|
|
15
|
+
* `createYielder` returns a `maybeYield()` that yields (via `setImmediate`) only
|
|
16
|
+
* once more than `budgetMs` of wall-clock has elapsed since the last yield, so
|
|
17
|
+
* fast repos pay essentially nothing while slow ones give the heartbeat a
|
|
18
|
+
* regular window to fire. Call it at natural boundaries in a long loop (between
|
|
19
|
+
* batches, between synthesis passes).
|
|
20
|
+
*
|
|
21
|
+
* This does NOT weaken the watchdog. A genuinely wedged loop — an infinite or
|
|
22
|
+
* non-terminating span, the case the watchdog exists to catch — never reaches a
|
|
23
|
+
* yield point, so the heartbeat still stops and the SIGKILL still fires. We only
|
|
24
|
+
* stop killing work that is demonstrably making progress.
|
|
25
|
+
*/
|
|
26
|
+
/** Yield when more than `budgetMs` of wall-clock has passed since the last yield. */
|
|
27
|
+
export type MaybeYield = () => Promise<void>;
|
|
28
|
+
/** Default budget: well under the watchdog's minimum heartbeat cadence (~1s), so
|
|
29
|
+
* a heartbeat byte always has a chance to land between yields. */
|
|
30
|
+
export declare const DEFAULT_YIELD_BUDGET_MS = 250;
|
|
31
|
+
export declare function createYielder(budgetMs?: number): MaybeYield;
|
|
32
|
+
//# sourceMappingURL=cooperative-yield.d.ts.map
|
|
@@ -103,7 +103,16 @@ export declare class ReferenceResolver {
|
|
|
103
103
|
* (re-resolving an already-resolved ref is a no-op since it's been deleted).
|
|
104
104
|
* Returns the number of newly-created edges.
|
|
105
105
|
*/
|
|
106
|
-
resolveChainedCallsViaConformance(): number
|
|
106
|
+
resolveChainedCallsViaConformance(): Promise<number>;
|
|
107
|
+
/**
|
|
108
|
+
* Resolve one batch in smaller sub-chunks, yielding to the event loop between
|
|
109
|
+
* them so the #850 liveness heartbeat can fire on a slow/dense batch (#1091).
|
|
110
|
+
* Behaviourally identical to a single `resolveAll(batch)`: `warmCaches()` is
|
|
111
|
+
* idempotent (guarded) and `resolveOne` is independent per ref, so splitting
|
|
112
|
+
* and re-merging changes only timing, never which edges get created. Falls
|
|
113
|
+
* through to a plain `resolveAll` when the batch is already small.
|
|
114
|
+
*/
|
|
115
|
+
private resolveBatchYielding;
|
|
107
116
|
/**
|
|
108
117
|
* Resolve and persist in batches to keep memory bounded.
|
|
109
118
|
* Processes unresolved references in chunks, persisting edges and cleaning
|
|
@@ -172,7 +181,7 @@ export declare class ReferenceResolver {
|
|
|
172
181
|
* Mirrors resolveChainedCallsViaConformance's lifecycle. Returns the number
|
|
173
182
|
* of newly-created edges.
|
|
174
183
|
*/
|
|
175
|
-
resolveDeferredThisMemberRefs(): number
|
|
184
|
+
resolveDeferredThisMemberRefs(): Promise<number>;
|
|
176
185
|
private gateLanguage;
|
|
177
186
|
/**
|
|
178
187
|
* Drop a FRAMEWORK-strategy resolution that crosses two *known* language
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles symbol name matching for reference resolution.
|
|
5
5
|
*/
|
|
6
|
+
import { Node } from '../types';
|
|
6
7
|
import { UnresolvedRef, ResolvedRef, ResolutionContext } from './types';
|
|
7
8
|
/**
|
|
8
9
|
* Try to resolve a path-like reference (e.g., "snippets/drawer-menu.liquid")
|
|
@@ -47,6 +48,27 @@ export declare function matchByExactName(ref: UnresolvedRef, context: Resolution
|
|
|
47
48
|
* Try to resolve by qualified name
|
|
48
49
|
*/
|
|
49
50
|
export declare function matchByQualifiedName(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
51
|
+
/**
|
|
52
|
+
* When a symbol name is ambiguous across files, prefer the candidate(s) declared
|
|
53
|
+
* in the call site's own file, keeping the rest in their original order (#1079).
|
|
54
|
+
* A same-file definition is the strongest language-agnostic signal for which of
|
|
55
|
+
* several same-named symbols a call means; without it, resolution collapses onto
|
|
56
|
+
* whichever was indexed first, so a call in `b/svc` wrongly targets `a/svc`.
|
|
57
|
+
* No-op when there are <2 candidates or none share the call site's file.
|
|
58
|
+
*/
|
|
59
|
+
export declare function preferCallSiteFile(nodes: Node[], callSiteFile: string): Node[];
|
|
60
|
+
export declare function resolveMethodOnType(typeName: string, methodName: string, ref: UnresolvedRef, context: ResolutionContext, confidence: number, resolvedBy: ResolvedRef['resolvedBy'],
|
|
61
|
+
/**
|
|
62
|
+
* Optional FQN that identifies WHICH class declaration `typeName`
|
|
63
|
+
* refers to in the caller's file. When multiple candidates share
|
|
64
|
+
* the same qualifiedName (`FooConverter::convert` in both
|
|
65
|
+
* `dao/converter/` and `service/converter/`), the FQN's
|
|
66
|
+
* file-path-suffix picks the right one — the disambiguation
|
|
67
|
+
* signal Java imports carry but the call site doesn't (#314).
|
|
68
|
+
*/
|
|
69
|
+
preferredFqn?: string,
|
|
70
|
+
/** Recursion guard for the supertype/conformance walk. */
|
|
71
|
+
depth?: number): ResolvedRef | null;
|
|
50
72
|
/**
|
|
51
73
|
* Resolve a C++ chained call whose receiver is itself a call — encoded by the
|
|
52
74
|
* extractor as `<innerCallee>().<method>` (#645). The receiver's type is what
|
package/npm-shim.js
CHANGED
|
@@ -45,7 +45,7 @@ async function main() {
|
|
|
45
45
|
// Happy path: the npm-installed optional dependency. Fall back to a download
|
|
46
46
|
// when the registry didn't deliver it.
|
|
47
47
|
var resolved = resolveInstalledBundle() || (await selfHealBundle());
|
|
48
|
-
var res = childProcess.spawnSync(resolved.command, resolved.args, { stdio: 'inherit' });
|
|
48
|
+
var res = childProcess.spawnSync(resolved.command, resolved.args, { stdio: 'inherit', windowsHide: true });
|
|
49
49
|
if (res.error) {
|
|
50
50
|
process.stderr.write('codegraph: ' + res.error.message + '\n');
|
|
51
51
|
process.exit(1);
|
|
@@ -222,7 +222,7 @@ function extract(archive, destDir) {
|
|
|
222
222
|
var args = isWindows
|
|
223
223
|
? ['-xf', archive, '-C', destDir, '--strip-components=1']
|
|
224
224
|
: ['-xzf', archive, '-C', destDir, '--strip-components=1'];
|
|
225
|
-
var res = childProcess.spawnSync('tar', args, { stdio: 'ignore' });
|
|
225
|
+
var res = childProcess.spawnSync('tar', args, { stdio: 'ignore', windowsHide: true });
|
|
226
226
|
if (res.error) throw new Error('tar unavailable: ' + res.error.message);
|
|
227
227
|
if (res.status !== 0) throw new Error('tar exited ' + res.status);
|
|
228
228
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colbymchenry/codegraph",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Local-first code intelligence for AI agents (MCP). Self-contained — bundles its own runtime.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"codegraph": "npm-shim.js"
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
"./package.json": "./package.json"
|
|
16
16
|
},
|
|
17
17
|
"optionalDependencies": {
|
|
18
|
-
"@colbymchenry/codegraph-darwin-arm64": "1.
|
|
19
|
-
"@colbymchenry/codegraph-darwin-x64": "1.
|
|
20
|
-
"@colbymchenry/codegraph-linux-arm64": "1.
|
|
21
|
-
"@colbymchenry/codegraph-linux-x64": "1.
|
|
22
|
-
"@colbymchenry/codegraph-win32-arm64": "1.
|
|
23
|
-
"@colbymchenry/codegraph-win32-x64": "1.
|
|
18
|
+
"@colbymchenry/codegraph-darwin-arm64": "1.2.0",
|
|
19
|
+
"@colbymchenry/codegraph-darwin-x64": "1.2.0",
|
|
20
|
+
"@colbymchenry/codegraph-linux-arm64": "1.2.0",
|
|
21
|
+
"@colbymchenry/codegraph-linux-x64": "1.2.0",
|
|
22
|
+
"@colbymchenry/codegraph-win32-arm64": "1.2.0",
|
|
23
|
+
"@colbymchenry/codegraph-win32-x64": "1.2.0"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"npm-shim.js",
|