@colbymchenry/codegraph 0.9.8 → 1.0.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 +150 -70
- package/dist/bin/codegraph.d.ts +1 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/markers.d.ts +19 -0
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/queries.d.ts +43 -0
- package/dist/db/sqlite-adapter.d.ts +7 -0
- package/dist/directory.d.ts +34 -2
- package/dist/extraction/astro-extractor.d.ts +79 -0
- package/dist/extraction/extraction-version.d.ts +25 -0
- package/dist/extraction/function-ref.d.ts +118 -0
- package/dist/extraction/grammars.d.ts +7 -1
- package/dist/extraction/index.d.ts +34 -0
- package/dist/extraction/languages/c-cpp.d.ts +8 -0
- package/dist/extraction/languages/csharp.d.ts +22 -0
- package/dist/extraction/languages/r.d.ts +3 -0
- package/dist/extraction/languages/typescript.d.ts +13 -0
- package/dist/extraction/liquid-extractor.d.ts +7 -0
- package/dist/extraction/razor-extractor.d.ts +42 -0
- package/dist/extraction/tree-sitter-types.d.ts +33 -0
- package/dist/extraction/tree-sitter.d.ts +237 -0
- package/dist/extraction/vue-extractor.d.ts +15 -0
- package/dist/index.d.ts +41 -3
- package/dist/installer/instructions-template.d.ts +34 -11
- package/dist/installer/targets/opencode.d.ts +9 -1
- package/dist/installer/targets/shared.d.ts +14 -0
- package/dist/mcp/daemon.d.ts +60 -1
- package/dist/mcp/dynamic-boundaries.d.ts +41 -0
- package/dist/mcp/ppid-watchdog.d.ts +44 -0
- package/dist/mcp/proxy.d.ts +6 -0
- package/dist/mcp/server-instructions.d.ts +12 -1
- package/dist/mcp/session.d.ts +2 -0
- package/dist/mcp/stdin-teardown.d.ts +27 -0
- package/dist/mcp/tools.d.ts +110 -49
- package/dist/resolution/callback-synthesizer.d.ts +3 -3
- package/dist/resolution/frameworks/astro.d.ts +9 -0
- package/dist/resolution/frameworks/index.d.ts +1 -0
- package/dist/resolution/import-resolver.d.ts +10 -0
- package/dist/resolution/index.d.ts +80 -0
- package/dist/resolution/name-matcher.d.ts +61 -0
- package/dist/resolution/types.d.ts +27 -3
- package/dist/resolution/workspace-packages.d.ts +48 -0
- package/dist/search/query-utils.d.ts +35 -1
- package/dist/sync/watcher.d.ts +124 -32
- package/dist/telemetry/index.d.ts +146 -0
- package/dist/types.d.ts +25 -2
- package/dist/upgrade/index.d.ts +132 -0
- package/dist/utils.d.ts +30 -24
- package/package.json +7 -7
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared decision logic for the PPID watchdog (#277, #692).
|
|
3
|
+
*
|
|
4
|
+
* The watchdog's job: notice that the process we depend on — our parent, or the
|
|
5
|
+
* MCP host reached past an intermediate launcher — has died, so an orphaned
|
|
6
|
+
* proxy / direct server shuts itself down instead of leaking forever.
|
|
7
|
+
*
|
|
8
|
+
* Parent death surfaces differently per OS, and getting this wrong is what
|
|
9
|
+
* caused the unbounded daemon/proxy leak on Windows (#692, #576):
|
|
10
|
+
*
|
|
11
|
+
* - **POSIX** reparents an orphan to init (pid 1), so `process.ppid` *changes*
|
|
12
|
+
* the instant the parent dies. That divergence is the classic #277 signal.
|
|
13
|
+
* - **Windows** never reparents: `process.ppid` keeps reporting the original
|
|
14
|
+
* (now-dead) parent forever, so the change-check can never fire. There we
|
|
15
|
+
* must poll the original parent's *liveness* instead.
|
|
16
|
+
*
|
|
17
|
+
* The liveness fallback is deliberately gated to Windows. On POSIX a
|
|
18
|
+
* double-forked grandparent can legitimately outlive the reparent, so a dead
|
|
19
|
+
* `originalPpid` is not proof of orphaning there — the change-check is the
|
|
20
|
+
* correct and sufficient POSIX signal, and using liveness too would risk a
|
|
21
|
+
* false-positive shutdown.
|
|
22
|
+
*/
|
|
23
|
+
export interface SupervisionState {
|
|
24
|
+
/** `process.ppid` captured at startup. */
|
|
25
|
+
originalPpid: number;
|
|
26
|
+
/** `process.ppid` right now. */
|
|
27
|
+
currentPpid: number;
|
|
28
|
+
/**
|
|
29
|
+
* The MCP host pid threaded past an intermediate launcher
|
|
30
|
+
* (`CODEGRAPH_HOST_PPID`), or null when unknown — e.g. the standalone bundle,
|
|
31
|
+
* which pre-bakes `--liftoff-only` and so never runs the relaunch that sets it.
|
|
32
|
+
*/
|
|
33
|
+
hostPpid: number | null;
|
|
34
|
+
/** Liveness probe — `process.kill(pid, 0)` in production, stubbed in tests. */
|
|
35
|
+
isAlive: (pid: number) => boolean;
|
|
36
|
+
/** Defaults to `process.platform`. */
|
|
37
|
+
platform?: NodeJS.Platform;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns a human-readable reason string when the process has lost its
|
|
41
|
+
* supervisor and should shut down, or null while it is still supervised.
|
|
42
|
+
*/
|
|
43
|
+
export declare function supervisionLostReason(state: SupervisionState): string | null;
|
|
44
|
+
//# sourceMappingURL=ppid-watchdog.d.ts.map
|
package/dist/mcp/proxy.d.ts
CHANGED
|
@@ -18,7 +18,13 @@
|
|
|
18
18
|
* the direct-mode server uses; see issue #277.
|
|
19
19
|
*/
|
|
20
20
|
import * as net from 'net';
|
|
21
|
+
import { DaemonHello } from './daemon';
|
|
21
22
|
import type { MCPEngine } from './engine';
|
|
23
|
+
/**
|
|
24
|
+
* Log a successful daemon attach — gated behind {@link LOG_ATTACH_ENV} so it is
|
|
25
|
+
* silent by default (see #618). Exported for tests.
|
|
26
|
+
*/
|
|
27
|
+
export declare function logAttachedDaemon(socketPath: string, hello: DaemonHello): void;
|
|
22
28
|
export interface ProxyResult {
|
|
23
29
|
/**
|
|
24
30
|
* `proxied` — successfully attached to a same-version daemon and piped
|
|
@@ -15,5 +15,16 @@
|
|
|
15
15
|
* burn tokens. Reference only tools that exist on `main`; gate any
|
|
16
16
|
* conditional tools behind feature checks if/when they ship.
|
|
17
17
|
*/
|
|
18
|
-
export declare const SERVER_INSTRUCTIONS = "# Codegraph \u2014 code intelligence over an indexed knowledge graph\n\nCodegraph is a SQLite knowledge graph of every symbol, edge, and file\
|
|
18
|
+
export declare const SERVER_INSTRUCTIONS = "# Codegraph \u2014 code intelligence over an indexed knowledge graph\n\nCodegraph is a SQLite knowledge graph of every symbol, edge, and file in\nthe workspace \u2014 pre-computed structure you would otherwise re-derive by\nreading files (cached intelligence: thousands of parse/trace decisions you\ndon't pay to re-reason each run). Reads are sub-millisecond; the index lags\nwrites by ~1s through the file watcher. Reach for it BEFORE *and* while\nwriting or editing code \u2014 not just for questions: one call returns the\nverbatim source PLUS who calls it and what it affects, so you edit with the\nblast radius in view. More accurate context, in far fewer tokens and\nround-trips than reading files yourself.\n\n## Use codegraph instead of reading files \u2014 for questions AND edits\n\nWhether you're answering \"how does X work\" or implementing a change (fixing\na bug, adding a feature), reach for codegraph before you Read. For\nunderstanding, answer DIRECTLY \u2014 usually with ONE `codegraph_explore` call.\n`codegraph_explore` takes either a natural-language question or a bag of\nsymbol/file names and returns the verbatim source of the relevant symbols\ngrouped by file, so it is Read-equivalent and most often the ONLY\ncodegraph call you need. Codegraph IS the pre-built search index \u2014 so\ndelegating the lookup to a separate file-reading sub-task/agent, or\nrunning your own grep + read loop, repeats work codegraph already did and\ncosts more for the same answer. Reach for raw Read/Grep only to confirm a\nspecific detail codegraph didn't cover. A direct codegraph answer is\ntypically one to a few calls; a grep/read exploration is dozens.\n\n## Tool selection by intent\n\n- **Almost any question \u2014 \"how does X work\", architecture, a bug, \"what/where is X\", or surveying an area** \u2192 `codegraph_explore` (PRIMARY \u2014 call FIRST; ONE capped call returns the verbatim source of the relevant symbols grouped by file; most often the ONLY call you need)\n- **\"How does X reach/become Y? / the flow / the path from X to Y\"** \u2192 `codegraph_explore`, naming the symbols that span the flow (e.g. `mutateElement renderScene`) \u2014 it surfaces the call path among them, including dynamic-dispatch hops (callbacks, React re-render, JSX children) grep can't follow\n- **\"What is the symbol named X?\" (just its location)** \u2192 `codegraph_search`\n- **\"What calls this?\" / \"What would changing this break?\"** \u2192 `codegraph_callers` \u2014 EVERY call site with file:line, including where a function is **registered as a callback** (passed as an argument, assigned to a function pointer/field, listed in a handler table) \u2014 labeled \"via callback registration\" \u2014 so a function with no direct calls is NOT dead if it's wired up somewhere. When several UNRELATED symbols share a name (one `UserService` per monorepo app), it reports **one section per definition** (never a merged list) \u2014 pass `file` to focus the definition you mean. The wider blast radius arrives automatically on `codegraph_explore` (its \"Blast radius\" section) and `codegraph_node` (the dependents note)\n- **\"What does this call?\"** \u2192 `codegraph_node` with that symbol and `includeCode: true` \u2014 the body IS the callee list, and the caller/callee trail comes with it\n- **Reading a source FILE (any time you'd use the `Read` tool)** \u2192 `codegraph_node` with a `file` path and no `symbol`. It returns the file's **current source with line numbers \u2014 the same `<n>\\t<line>` shape `Read` gives you, safe to `Edit` from** \u2014 narrowable with `offset`/`limit` exactly like `Read`, PLUS a one-line note of which files depend on it. Same bytes as `Read`, faster (served from the index), with the blast radius attached. Use it **instead of `Read`** for indexed source files; fall back to `Read` only for what codegraph doesn't index (configs, docs). Pass `symbolsOnly: true` for just the file's structure.\n- **About to read or edit a symbol you can name** \u2192 `codegraph_node` with that `symbol` (SECONDARY \u2014 the after-explore depth tool): the verbatim source (`includeCode: true`) PLUS its caller/callee trail, so before changing it you see what calls it and what your edit would break. For an OVERLOADED name it returns EVERY matching definition's body in one call, so you never Read a file to find the right overload\n\n## Common chains\n\n- **Flow / \"how does X reach Y\"**: ONE `codegraph_explore` with the symbol names spanning the flow \u2014 it surfaces the call path among them (riding dynamic-dispatch hops) AND returns their source. No need to reconstruct the path with `codegraph_search` + `codegraph_callers`.\n- **Onboarding / understanding any area**: ONE `codegraph_explore` is usually the whole answer. Only follow up \u2014 `codegraph_node` for a specific symbol \u2014 if something is still unclear.\n- **Refactor planning**: `codegraph_callers` for the complete call-site list to update; the wider blast radius is already attached to `codegraph_explore` / `codegraph_node` output.\n- **Debugging a regression**: `codegraph_callers` of the suspected symbol; `codegraph_node` on anything unexpected that appears.\n\n## Anti-patterns\n\n- **Trust codegraph's results \u2014 don't re-verify them with grep.** They come from a full AST parse; re-checking with grep is slower, less accurate, and wastes context.\n- **Don't grep first** when looking up a symbol by name \u2014 `codegraph_search` is faster and returns kind + location + signature.\n- **Don't chain `codegraph_search` + `codegraph_node`** to understand an area \u2014 ONE `codegraph_explore` returns the relevant symbols' source together in a single round-trip.\n- **Don't loop `codegraph_node` over many symbols** \u2014 one `codegraph_explore` call returns them all grouped by file, while each separate call re-reads the whole context and costs far more. Use `codegraph_node` for a single symbol.\n- **Don't reach for the `Read` tool on an indexed source file** \u2014 `codegraph_node` with a `file` reads it for you (same `<n>\\t<line>` source, `offset`/`limit` like Read, faster, with its blast radius), and with a `symbol` it returns the source plus the caller/callee trail. Reach for raw `Read` only for what codegraph doesn't index (configs, docs) or when the staleness banner flags a file as pending re-index.\n- **After editing, check the staleness banner.** When a tool response starts with \"\u26A0\uFE0F Some files referenced below were edited since the last index sync\u2026\", the listed files are pending re-index \u2014 Read those specific files for accurate content. Every file NOT in that banner is fresh, so still trust codegraph.\n\n## Limitations\n\n- If a tool reports a project isn't indexed (no `.codegraph/`), stop calling codegraph tools for that project for the rest of the session and use your built-in tools there instead. Indexing is the user's decision \u2014 mention they can run `codegraph init` if it comes up, but don't run it yourself.\n- Index lags file writes by ~1 second.\n- Cross-file resolution is best-effort name matching; ambiguous calls may return multiple candidates.\n- No live correctness validation \u2014 that's still the TypeScript compiler / test suite / linter's job. Codegraph supplements those with structural context they don't have.\n";
|
|
19
|
+
/**
|
|
20
|
+
* Instructions variant sent when the workspace has NO codegraph index.
|
|
21
|
+
*
|
|
22
|
+
* Sending the full playbook ("lean on codegraph for everything") into a
|
|
23
|
+
* session where every call would fail wastes the agent's calls and — worse —
|
|
24
|
+
* the failures teach it codegraph is broken. The unindexed variant is a
|
|
25
|
+
* short, unambiguous "inactive this session" note; `tools/list` is gated to
|
|
26
|
+
* empty in the same state, so the agent has nothing to mis-call. Indexing is
|
|
27
|
+
* deliberately left to the user: the agent is told NOT to run init itself.
|
|
28
|
+
*/
|
|
29
|
+
export declare const SERVER_INSTRUCTIONS_UNINDEXED = "# Codegraph \u2014 inactive (workspace not indexed)\n\nThis workspace has no codegraph index (no `.codegraph/` directory), so no\ncodegraph tools are available this session. Work with your built-in tools as\nusual.\n\nIndexing is the user's decision \u2014 do not run it yourself. If the user asks\nabout codegraph, they can enable it by running `codegraph init` in the\nproject root and starting a new session.\n";
|
|
19
30
|
//# sourceMappingURL=server-instructions.d.ts.map
|
package/dist/mcp/session.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export declare class MCPSession {
|
|
|
39
39
|
private transport;
|
|
40
40
|
private engine;
|
|
41
41
|
private clientSupportsRoots;
|
|
42
|
+
/** From the initialize handshake — attributes usage rollups to the agent host. */
|
|
43
|
+
private clientInfo;
|
|
42
44
|
private rootsAttempted;
|
|
43
45
|
private resolvePromise;
|
|
44
46
|
private explicitProjectPath;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Treat a stdin failure as a shutdown signal — issue #799.
|
|
3
|
+
*
|
|
4
|
+
* An MCP stdio server's lifeline is its stdin: when the host/client goes away,
|
|
5
|
+
* stdin should end and the server should exit. The server paths listened for
|
|
6
|
+
* `'end'` and `'close'` — but NOT `'error'`.
|
|
7
|
+
*
|
|
8
|
+
* That gap bites with a socket-backed stdin, which is the shape VS Code /
|
|
9
|
+
* Claude Code use (a socketpair, not a pipe). When the client dies, the socket
|
|
10
|
+
* can surface as an `'error'` (ECONNRESET / hangup) rather than a clean
|
|
11
|
+
* `'close'`. With no `'error'` listener, Node escalates it to the process-wide
|
|
12
|
+
* `uncaughtException` handler, which logs and keeps running — so the server
|
|
13
|
+
* orphans instead of exiting. Worse, on Linux a `POLLHUP` socket fd left
|
|
14
|
+
* registered in epoll wakes the event loop continuously, pinning a core at
|
|
15
|
+
* 100% CPU (the spin reported in #799); once the main thread spins, the
|
|
16
|
+
* `setInterval` PPID watchdog can't even fire, so the orphan runs forever.
|
|
17
|
+
*
|
|
18
|
+
* Fix: listen for `'error'` as well, and DESTROY the stdin stream on any
|
|
19
|
+
* terminal event so the fd leaves epoll and can't keep churning, then run the
|
|
20
|
+
* caller's shutdown. Fires `onTerminal` at most once — callers' shutdowns are
|
|
21
|
+
* already re-entry-guarded, but the single-shot guard also keeps `destroy()`'s
|
|
22
|
+
* follow-on `'close'` from re-invoking it.
|
|
23
|
+
*
|
|
24
|
+
* `stream` is injectable for tests; it defaults to `process.stdin`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function treatStdinFailureAsShutdown(onTerminal: () => void, stream?: NodeJS.ReadableStream): void;
|
|
27
|
+
//# sourceMappingURL=stdin-teardown.d.ts.map
|
package/dist/mcp/tools.d.ts
CHANGED
|
@@ -5,6 +5,25 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type CodeGraph from '../index';
|
|
7
7
|
import type { PendingFile } from '../sync';
|
|
8
|
+
/**
|
|
9
|
+
* An expected, recoverable "codegraph can't serve this" condition — most
|
|
10
|
+
* importantly a project with no index. The dispatch catch converts these to
|
|
11
|
+
* SUCCESS-shaped responses (guidance text, NO isError): an `isError: true`
|
|
12
|
+
* early in a session teaches the agent the toolset is broken and it stops
|
|
13
|
+
* calling codegraph entirely (observed repeatedly), which is exactly wrong
|
|
14
|
+
* for conditions the agent can simply work around (use built-in tools for
|
|
15
|
+
* that codebase / pass projectPath). isError is reserved for "stop trying"
|
|
16
|
+
* cases: security refusals ({@link PathRefusalError}) and genuine
|
|
17
|
+
* malfunctions.
|
|
18
|
+
*/
|
|
19
|
+
export declare class NotIndexedError extends Error {
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A security refusal (sensitive system path). Stays `isError: true` WITHOUT
|
|
23
|
+
* retry guidance — abandoning this path is the desired agent reaction.
|
|
24
|
+
*/
|
|
25
|
+
export declare class PathRefusalError extends Error {
|
|
26
|
+
}
|
|
8
27
|
/**
|
|
9
28
|
* Calculate the recommended number of codegraph_explore calls based on project size.
|
|
10
29
|
* Larger codebases need more exploration calls to cover their surface area,
|
|
@@ -105,8 +124,9 @@ export interface ToolResult {
|
|
|
105
124
|
/**
|
|
106
125
|
* All CodeGraph MCP tools
|
|
107
126
|
*
|
|
108
|
-
* Designed for minimal context usage - use
|
|
109
|
-
* and only use other tools for
|
|
127
|
+
* Designed for minimal context usage - use codegraph_explore as the primary tool
|
|
128
|
+
* (one call usually answers the whole question), and only use other tools for
|
|
129
|
+
* targeted follow-up queries.
|
|
110
130
|
*
|
|
111
131
|
* All tools support cross-project queries via the optional `projectPath` parameter.
|
|
112
132
|
*/
|
|
@@ -158,7 +178,7 @@ export declare class ToolHandler {
|
|
|
158
178
|
* Unset/empty → every tool is exposed. Lets an operator (or an A/B harness)
|
|
159
179
|
* trim the tool surface without rebuilding the client config; the ablated
|
|
160
180
|
* tool is then truly absent from ListTools rather than merely denied on call.
|
|
161
|
-
* Matching is on the short form, so "
|
|
181
|
+
* Matching is on the short form, so "node" and "codegraph_node" both work.
|
|
162
182
|
*/
|
|
163
183
|
private toolAllowlist;
|
|
164
184
|
/** Whether a tool name passes the CODEGRAPH_MCP_TOOLS allowlist (if any). */
|
|
@@ -241,26 +261,15 @@ export declare class ToolHandler {
|
|
|
241
261
|
*/
|
|
242
262
|
private handleSearch;
|
|
243
263
|
/**
|
|
244
|
-
*
|
|
264
|
+
* Group symbol matches into DISTINCT DEFINITIONS — one group per
|
|
265
|
+
* (filePath, qualifiedName), so same-file overloads stay together while
|
|
266
|
+
* unrelated same-named classes across a monorepo's apps (#764: one
|
|
267
|
+
* `UserService` per NestJS app) are kept apart. Optionally narrowed by a
|
|
268
|
+
* `file` path/suffix first.
|
|
245
269
|
*/
|
|
246
|
-
private
|
|
247
|
-
/**
|
|
248
|
-
|
|
249
|
-
* and pre-run trace between the most likely endpoints, returning the trace
|
|
250
|
-
* body to splice into the context response. Returns '' for non-flow queries
|
|
251
|
-
* or when no plausible endpoint pair can be extracted.
|
|
252
|
-
*
|
|
253
|
-
* Conservative by design: only fires when the task has both a clear flow
|
|
254
|
-
* keyword AND at least two distinct PascalCase / camelCase identifiers.
|
|
255
|
-
* False positives waste a graph query; false negatives just fall back to
|
|
256
|
-
* the agent calling trace itself (existing path-proximity wiring handles
|
|
257
|
-
* disambiguation either way).
|
|
258
|
-
*/
|
|
259
|
-
private maybeInlineFlowTrace;
|
|
260
|
-
/**
|
|
261
|
-
* Heuristic to detect if a query looks like a feature request
|
|
262
|
-
*/
|
|
263
|
-
private looksLikeFeatureRequest;
|
|
270
|
+
private groupDefinitions;
|
|
271
|
+
/** Section heading for one distinct definition in grouped output. */
|
|
272
|
+
private definitionHeading;
|
|
264
273
|
/**
|
|
265
274
|
* Handle codegraph_callers
|
|
266
275
|
*/
|
|
@@ -273,18 +282,6 @@ export declare class ToolHandler {
|
|
|
273
282
|
* Handle codegraph_impact
|
|
274
283
|
*/
|
|
275
284
|
private handleImpact;
|
|
276
|
-
/**
|
|
277
|
-
* Handle codegraph_trace — shortest CALL PATH between two symbols.
|
|
278
|
-
*
|
|
279
|
-
* Exposes GraphTraverser.findPath: the chain of functions from `from` to `to`,
|
|
280
|
-
* each hop annotated with file:line and the call-site line. This is the
|
|
281
|
-
* capability grep/Read structurally cannot provide. When no static path
|
|
282
|
-
* exists, the chain has almost certainly broken at dynamic dispatch
|
|
283
|
-
* (callbacks, descriptors, metaclasses) — we say so and surface the start
|
|
284
|
-
* symbol's outgoing calls so the agent bridges the one missing hop with
|
|
285
|
-
* codegraph_node rather than blindly reading.
|
|
286
|
-
*/
|
|
287
|
-
private handleTrace;
|
|
288
285
|
/**
|
|
289
286
|
* Describe a synthesized (dynamic-dispatch) edge for human output: how the
|
|
290
287
|
* callback was wired up — the bridge static parsing can't see. Returns null
|
|
@@ -292,19 +289,6 @@ export declare class ToolHandler {
|
|
|
292
289
|
* hop reads as "registered via onUpdate at App.tsx:3148", not a bare arrow.
|
|
293
290
|
*/
|
|
294
291
|
private synthEdgeNote;
|
|
295
|
-
/**
|
|
296
|
-
* Read one trimmed source line at "relpath:line" (relative to the project
|
|
297
|
-
* root). `cache` holds split file contents so a multi-hop trace reads each
|
|
298
|
-
* file at most once. Returns null if the file/line can't be resolved.
|
|
299
|
-
*/
|
|
300
|
-
private sourceLineAt;
|
|
301
|
-
/**
|
|
302
|
-
* Read a hop's body — filePath lines [startLine..endLine] — for inlining into
|
|
303
|
-
* a trace, capped (lines + chars) so the whole path stays path-scoped even on
|
|
304
|
-
* a 7-hop chain. Dedents to the body's own indentation and marks truncation.
|
|
305
|
-
* Shares `cache` with sourceLineAt so each file is read at most once per trace.
|
|
306
|
-
*/
|
|
307
|
-
private sourceRangeAt;
|
|
308
292
|
/**
|
|
309
293
|
* Flow-from-named-symbols: an agent's codegraph_explore query is a bag of
|
|
310
294
|
* symbol names that usually spans the flow it's investigating (e.g.
|
|
@@ -320,6 +304,53 @@ export declare class ToolHandler {
|
|
|
320
304
|
* dropping unrelated `OmsOrderService::list`.
|
|
321
305
|
*/
|
|
322
306
|
private buildFlowFromNamedSymbols;
|
|
307
|
+
/**
|
|
308
|
+
* Dynamic-boundary surfacing (#687): when the flow among the agent's named
|
|
309
|
+
* symbols does not fully connect, scan the disconnected symbols' bodies for
|
|
310
|
+
* dynamic-dispatch sites (computed member calls, getattr, reflection, typed
|
|
311
|
+
* message buses, runtime-keyed emits) and ANNOUNCE the boundary — the exact
|
|
312
|
+
* site, the form, and (when a key is statically visible) candidate targets —
|
|
313
|
+
* instead of guessing edges. The answer to "how does A reach B" when no
|
|
314
|
+
* static path exists IS the dispatch site: that's where the flow continues
|
|
315
|
+
* at runtime. Query-time, deterministic, zero graph mutation; a fully
|
|
316
|
+
* connected flow never reaches this method.
|
|
317
|
+
*/
|
|
318
|
+
private buildDynamicBoundaries;
|
|
319
|
+
/**
|
|
320
|
+
* Shortlist candidate runtime targets for a dispatch key surfaced by
|
|
321
|
+
* {@link buildDynamicBoundaries}. Exact conventional names first (`save` →
|
|
322
|
+
* `onSave`/`handleSave`; `CreateCmd` → `CreateCmdHandler`), then FTS, with a
|
|
323
|
+
* normalized-containment post-filter (FTS camel-splitting is fuzzier than a
|
|
324
|
+
* candidate list should be). Symbols the agent already named sort first and
|
|
325
|
+
* are marked — that's the "you were right, here's the wiring" case.
|
|
326
|
+
*/
|
|
327
|
+
private boundaryCandidates;
|
|
328
|
+
/**
|
|
329
|
+
* Compact "blast radius" for the entry symbols of an explore result: who
|
|
330
|
+
* depends on each (callers) and which test files cover it — LOCATIONS ONLY,
|
|
331
|
+
* no source, so the agent knows what to update / re-verify before editing
|
|
332
|
+
* without reaching for a separate impact call. Always-on, but skips symbols
|
|
333
|
+
* that have no dependents (nothing to warn about), and returns '' when none
|
|
334
|
+
* qualify so a leaf-only exploration stays clean.
|
|
335
|
+
*/
|
|
336
|
+
private buildBlastRadiusSection;
|
|
337
|
+
/**
|
|
338
|
+
* Graph-connectivity relevance via Random-Walk-with-Restart (personalized
|
|
339
|
+
* PageRank) from the query's matched SEED nodes over the call/reference graph.
|
|
340
|
+
*
|
|
341
|
+
* This is the ranking signal text search (FTS/bm25) CANNOT provide, and it's
|
|
342
|
+
* codegraph's home turf: relevance by STRUCTURE, not words. A file whose
|
|
343
|
+
* symbols are call-connected to the matched cluster accrues walk mass and
|
|
344
|
+
* ranks high; a lone TEXT match — e.g. `LensSwitcher.swift` matched the word
|
|
345
|
+
* "switch" from `switchOrganization`, but calls none of `setUser`/`fetchUser`
|
|
346
|
+
* — gets only its own restart probability and ranks ~0. Immune to the
|
|
347
|
+
* tokenization trap that fools term matching, deterministic, no embeddings.
|
|
348
|
+
*
|
|
349
|
+
* Undirected adjacency (reachability both ways), restart α=0.25 to the seeds,
|
|
350
|
+
* power iteration to convergence. Bounded to the already-relevant subgraph, so
|
|
351
|
+
* it's a few hundred nodes × ~25 iterations — negligible cost.
|
|
352
|
+
*/
|
|
353
|
+
private computeGraphRelevance;
|
|
323
354
|
/**
|
|
324
355
|
* Handle codegraph_explore — deep exploration in a single call
|
|
325
356
|
*
|
|
@@ -336,6 +367,22 @@ export declare class ToolHandler {
|
|
|
336
367
|
* Handle codegraph_node
|
|
337
368
|
*/
|
|
338
369
|
private handleNode;
|
|
370
|
+
/**
|
|
371
|
+
* FILE READ MODE: resolve `fileArg` (path or basename) to an indexed file and
|
|
372
|
+
* read it like the Read tool — its current on-disk source with line numbers,
|
|
373
|
+
* narrowable with `offset`/`limit` exactly as Read's are — preceded by a
|
|
374
|
+
* one-line blast-radius header (which files depend on it). `symbolsOnly`
|
|
375
|
+
* returns just the structural map (symbols + dependents) instead of source.
|
|
376
|
+
*
|
|
377
|
+
* Parity goal: the numbered source block is byte-for-byte the shape Read
|
|
378
|
+
* returns (`<n>\t<line>`, no padding), so the agent treats it as a Read — only
|
|
379
|
+
* faster (served from the index) and with the blast radius attached. Security:
|
|
380
|
+
* yaml/properties files are summarized by key, never dumped (#383); reads go
|
|
381
|
+
* through validatePathWithinRoot (#527).
|
|
382
|
+
*/
|
|
383
|
+
private handleFileView;
|
|
384
|
+
/** Render one symbol: details + (optional) body/outline + its caller/callee trail. */
|
|
385
|
+
private renderNodeSection;
|
|
339
386
|
/**
|
|
340
387
|
* Build the "trail" for a symbol: its direct callees (what it calls) and
|
|
341
388
|
* callers (what calls it), each with file:line — so codegraph_node doubles as
|
|
@@ -393,7 +440,15 @@ export declare class ToolHandler {
|
|
|
393
440
|
* Python — `stage_apply::run` matches a `run` in `stage_apply.rs`)
|
|
394
441
|
*/
|
|
395
442
|
private matchesSymbol;
|
|
396
|
-
|
|
443
|
+
/**
|
|
444
|
+
* Find ALL definitions matching a name, ranked, so codegraph_node can return
|
|
445
|
+
* every overload instead of guessing one (the wrong guess → a Read). Keepers
|
|
446
|
+
* rank before generated stubs (.pb.go etc.); stable within a group preserves
|
|
447
|
+
* FTS order. Returns [] when nothing matches; a qualified lookup that finds no
|
|
448
|
+
* exact match returns [] rather than a misleading fuzzy file hit (#173); a
|
|
449
|
+
* bare name with no exact match falls back to the single top fuzzy result.
|
|
450
|
+
*/
|
|
451
|
+
private findSymbolMatches;
|
|
397
452
|
/**
|
|
398
453
|
* Find ALL symbols matching a name. Used by callers/callees/impact to aggregate
|
|
399
454
|
* results across all matching symbols (e.g., multiple classes with an `execute` method).
|
|
@@ -405,6 +460,13 @@ export declare class ToolHandler {
|
|
|
405
460
|
private truncateOutput;
|
|
406
461
|
private formatSearchResults;
|
|
407
462
|
private formatNodeList;
|
|
463
|
+
/**
|
|
464
|
+
* Relationship label for a non-`calls` edge in callers/callees lists. A
|
|
465
|
+
* function-as-value edge (#756) is the high-signal one: `callers(cb)`
|
|
466
|
+
* showing "via callback registration" tells the agent this is where the
|
|
467
|
+
* callback is WIRED, not where it's invoked.
|
|
468
|
+
*/
|
|
469
|
+
private edgeLabel;
|
|
408
470
|
private formatImpact;
|
|
409
471
|
/**
|
|
410
472
|
* Build a compact structural outline of a container symbol from its
|
|
@@ -415,7 +477,6 @@ export declare class ToolHandler {
|
|
|
415
477
|
*/
|
|
416
478
|
private buildContainerOutline;
|
|
417
479
|
private formatNodeDetails;
|
|
418
|
-
private formatTaskContext;
|
|
419
480
|
private textResult;
|
|
420
481
|
private errorResult;
|
|
421
482
|
}
|
|
@@ -2,9 +2,9 @@ import type { QueryBuilder } from '../db/queries';
|
|
|
2
2
|
import type { ResolutionContext } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Synthesize dispatcher→callback edges (field observers + EventEmitters +
|
|
5
|
-
* React re-render + JSX children + Vue templates + RN event
|
|
6
|
-
* Fabric native-impl + MyBatis Java↔XML + Gin middleware chain).
|
|
7
|
-
* count added. Never throws into indexing — callers wrap in try/catch.
|
|
5
|
+
* React re-render + JSX children + Vue templates + SvelteKit load + RN event
|
|
6
|
+
* channel + Fabric native-impl + MyBatis Java↔XML + Gin middleware chain).
|
|
7
|
+
* Returns the count added. Never throws into indexing — callers wrap in try/catch.
|
|
8
8
|
*/
|
|
9
9
|
export declare function synthesizeCallbackEdges(queries: QueryBuilder, ctx: ResolutionContext): number;
|
|
10
10
|
//# sourceMappingURL=callback-synthesizer.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Astro Framework Resolver
|
|
3
|
+
*
|
|
4
|
+
* Handles Astro component references, the `Astro` global, `astro:*` virtual
|
|
5
|
+
* module imports, and Astro's `src/pages/` file-based routing.
|
|
6
|
+
*/
|
|
7
|
+
import { FrameworkResolver } from '../types';
|
|
8
|
+
export declare const astroResolver: FrameworkResolver;
|
|
9
|
+
//# sourceMappingURL=astro.d.ts.map
|
|
@@ -33,6 +33,7 @@ export { nestjsResolver } from './nestjs';
|
|
|
33
33
|
export { reactResolver } from './react';
|
|
34
34
|
export { svelteResolver } from './svelte';
|
|
35
35
|
export { vueResolver } from './vue';
|
|
36
|
+
export { astroResolver } from './astro';
|
|
36
37
|
export { djangoResolver, flaskResolver, fastapiResolver } from './python';
|
|
37
38
|
export { railsResolver } from './ruby';
|
|
38
39
|
export { springResolver } from './java';
|
|
@@ -27,6 +27,16 @@ export declare function clearCppIncludeDirCache(): void;
|
|
|
27
27
|
* Returns paths relative to projectRoot.
|
|
28
28
|
*/
|
|
29
29
|
export declare function loadCppIncludeDirs(projectRoot: string): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Is this reference a PHP include/require PATH (vs a namespace `use` symbol)?
|
|
32
|
+
*
|
|
33
|
+
* include/require emit a file path ("lib.php", "inc/db.php", "../x.php"),
|
|
34
|
+
* whereas namespace use is an FQN (App\Foo\Bar) or a bare class symbol
|
|
35
|
+
* (Closure). PHP identifiers contain neither '/' nor '.', so a slash or dot
|
|
36
|
+
* marks a path-shaped include. Such references resolve to files only — never
|
|
37
|
+
* to a same-named symbol — so callers must not fall back to the name-matcher.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isPhpIncludePathRef(ref: UnresolvedRef): boolean;
|
|
30
40
|
/**
|
|
31
41
|
* Extract import mappings from a file
|
|
32
42
|
*/
|
|
@@ -17,6 +17,9 @@ export declare class ReferenceResolver {
|
|
|
17
17
|
private queries;
|
|
18
18
|
private context;
|
|
19
19
|
private frameworks;
|
|
20
|
+
private deferredChainRefs;
|
|
21
|
+
private deferredThisMemberRefs;
|
|
22
|
+
private razorUsingsCache;
|
|
20
23
|
private nodeCache;
|
|
21
24
|
private fileCache;
|
|
22
25
|
private importMappingCache;
|
|
@@ -29,6 +32,7 @@ export declare class ReferenceResolver {
|
|
|
29
32
|
private cachesWarmed;
|
|
30
33
|
private projectAliases;
|
|
31
34
|
private goModule;
|
|
35
|
+
private workspacePackages;
|
|
32
36
|
constructor(projectRoot: string, queries: QueryBuilder);
|
|
33
37
|
/**
|
|
34
38
|
* Initialize the resolver (detect frameworks, etc.)
|
|
@@ -86,6 +90,20 @@ export declare class ReferenceResolver {
|
|
|
86
90
|
* Resolve and persist edges to database
|
|
87
91
|
*/
|
|
88
92
|
resolveAndPersist(unresolvedRefs: UnresolvedReference[], onProgress?: (current: number, total: number) => void): ResolutionResult;
|
|
93
|
+
/**
|
|
94
|
+
* Second resolution pass for chained static-factory / fluent calls whose
|
|
95
|
+
* chained method is defined on a SUPERTYPE the receiver's type conforms to —
|
|
96
|
+
* a protocol-extension / inherited / default-interface method (#750). The
|
|
97
|
+
* first pass can't resolve these because `implements`/`extends` edges aren't
|
|
98
|
+
* built yet; this runs AFTER edges are persisted, so `context.getSupertypes`
|
|
99
|
+
* (and the conformance fallback in resolveMethodOnType) can walk them.
|
|
100
|
+
*
|
|
101
|
+
* Operates only on the leftover unresolved refs that have the `inner().method`
|
|
102
|
+
* chain shape, for the dotted-chain languages — a small set — and is idempotent
|
|
103
|
+
* (re-resolving an already-resolved ref is a no-op since it's been deleted).
|
|
104
|
+
* Returns the number of newly-created edges.
|
|
105
|
+
*/
|
|
106
|
+
resolveChainedCallsViaConformance(): number;
|
|
89
107
|
/**
|
|
90
108
|
* Resolve and persist in batches to keep memory bounded.
|
|
91
109
|
* Processes unresolved references in chunks, persisting edges and cleaning
|
|
@@ -108,6 +126,68 @@ export declare class ReferenceResolver {
|
|
|
108
126
|
* Get language from node ID
|
|
109
127
|
*/
|
|
110
128
|
private getLanguageFromNodeId;
|
|
129
|
+
/**
|
|
130
|
+
* Drop an import/name-strategy resolution that crosses a language family.
|
|
131
|
+
* Two regimes (mirrors `applyLanguageGate`'s candidate filter):
|
|
132
|
+
* - `references` (type usage): STRICT — a `Type.member` static read names a
|
|
133
|
+
* same-family type, never a coincidentally same-named symbol in another
|
|
134
|
+
* language. Drops any non-same-family target.
|
|
135
|
+
* - `imports` (import binding / `#include`): both-known — a C++ `#include
|
|
136
|
+
* "X.h"` must not resolve to a same-named ObjC header on another platform
|
|
137
|
+
* (basename collision), but a singleton-family / SFC language (`vue` →
|
|
138
|
+
* `.ts`) importing across is left alone.
|
|
139
|
+
* Applies to the import (strategy 2) + name-match (strategy 3) results.
|
|
140
|
+
*/
|
|
141
|
+
/**
|
|
142
|
+
* Collect the `@using` namespaces in scope for a `.razor`/`.cshtml` file: its
|
|
143
|
+
* own `@using` directives plus every `_Imports.razor` from the file's folder up
|
|
144
|
+
* to the project root (Razor `_Imports` cascade). Cached per file.
|
|
145
|
+
*/
|
|
146
|
+
private getRazorUsings;
|
|
147
|
+
/**
|
|
148
|
+
* Resolve a Razor/Blazor simple type ref through the file's `@using`
|
|
149
|
+
* namespaces: `CatalogBrand` + `@using BlazorShared.Models` → the node whose
|
|
150
|
+
* qualified name is `BlazorShared.Models::CatalogBrand`. Only resolves when the
|
|
151
|
+
* `@using` set yields exactly ONE type (otherwise it stays ambiguous and falls
|
|
152
|
+
* through to name-matching).
|
|
153
|
+
*/
|
|
154
|
+
private resolveRazorUsing;
|
|
155
|
+
/**
|
|
156
|
+
* Resolve a `this.<member>` function-as-value reference (#756/#808) to the
|
|
157
|
+
* ENCLOSING CLASS's own member — never a same-named symbol elsewhere. The
|
|
158
|
+
* registration idiom (`btn.on('click', this.handleClick)`) names a member
|
|
159
|
+
* of the class being defined, so the only valid target shares the
|
|
160
|
+
* from-symbol's qualified-name scope. Function/method targets only — a
|
|
161
|
+
* property (a data field, post-#808 classification) yields no edge — same
|
|
162
|
+
* file required, no fallback of any kind.
|
|
163
|
+
*/
|
|
164
|
+
private resolveThisMemberFnRef;
|
|
165
|
+
/**
|
|
166
|
+
* Second pass for `this.<member>` refs whose member wasn't on the enclosing
|
|
167
|
+
* class itself (#808): once implements/extends edges exist, walk the
|
|
168
|
+
* class's supertypes (transitively, depth-capped) and resolve the member on
|
|
169
|
+
* the nearest one that declares it — `this.handleSubmit` registered in a
|
|
170
|
+
* subclass resolves to `FormBase::handleSubmit`. Validated targets only
|
|
171
|
+
* (function/method kind, same language family); no match → no edge.
|
|
172
|
+
* Mirrors resolveChainedCallsViaConformance's lifecycle. Returns the number
|
|
173
|
+
* of newly-created edges.
|
|
174
|
+
*/
|
|
175
|
+
resolveDeferredThisMemberRefs(): number;
|
|
176
|
+
private gateLanguage;
|
|
177
|
+
/**
|
|
178
|
+
* Drop a FRAMEWORK-strategy resolution that crosses two *known* language
|
|
179
|
+
* families for a type-usage (`references`) or import-binding (`imports`)
|
|
180
|
+
* edge. The framework strategy is intentionally ungated for cross-language
|
|
181
|
+
* bridges, but those legitimate bridges are either `calls` edges (RN/Expo
|
|
182
|
+
* JS → native) or config↔code edges whose config side (`yaml`/`blade`/…) is
|
|
183
|
+
* not a known programming-language family. A `references`/`imports` edge
|
|
184
|
+
* between two *known* families is always a coincidental name collision — the
|
|
185
|
+
* React/Svelte/Vue PascalCase component resolvers name-match `getNodesByName`
|
|
186
|
+
* without a language check, so a TS `<TestRunner>` ref happily matched a
|
|
187
|
+
* Kotlin `class TestRunner`. Gating only the both-known-cross-family case
|
|
188
|
+
* lets config bridges and `calls` bridges through untouched.
|
|
189
|
+
*/
|
|
190
|
+
private gateFrameworkLanguage;
|
|
111
191
|
}
|
|
112
192
|
/**
|
|
113
193
|
* Create a reference resolver instance
|
|
@@ -9,6 +9,36 @@ import { UnresolvedRef, ResolvedRef, ResolutionContext } from './types';
|
|
|
9
9
|
* by matching the filename against file nodes.
|
|
10
10
|
*/
|
|
11
11
|
export declare function matchByFilePath(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
12
|
+
export declare function sameLanguageFamily(a: string, b: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* True when `lang` belongs to a known multi-language family (jvm/apple/web/c).
|
|
15
|
+
* Languages not listed (php, python, go, ruby, rust, dart, …) and config
|
|
16
|
+
* formats (yaml/xml/blade) form their own singleton families and return
|
|
17
|
+
* `false` — used to leave config↔code framework bridges (whose config side is
|
|
18
|
+
* never a known programming-language family) out of the cross-family gate.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isKnownLanguageFamily(lang: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* True when `a` and `b` are two DIFFERENT *known* language families — the
|
|
23
|
+
* signature of a coincidental cross-language name collision (a TS `import
|
|
24
|
+
* React` matching a Swift `import React`, a C++ `#include "X.h"` matching a
|
|
25
|
+
* same-named ObjC header on another platform). The both-*known* test is
|
|
26
|
+
* deliberately weaker than {@link sameLanguageFamily}'s negation: a
|
|
27
|
+
* single-file-component language that carries its own tag (`vue`/`svelte`)
|
|
28
|
+
* importing a `.ts` module, or any singleton-family language (php/go/ruby/…),
|
|
29
|
+
* returns `false` here and is left alone.
|
|
30
|
+
*/
|
|
31
|
+
export declare function crossesKnownFamily(a: string, b: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve a function-as-value reference (#756) — a function name used as a
|
|
34
|
+
* callback/function-pointer value (`register(handler)`, `o->cb = handler`,
|
|
35
|
+
* `{ .cb = handler }`, `signal(SIGINT, handler)`). The ONLY strategy allowed
|
|
36
|
+
* for `function_ref` refs: exact name, function/method targets only, same
|
|
37
|
+
* language family, same-file first, and cross-file only when the match is
|
|
38
|
+
* UNIQUE. No fuzzy fallback, no qualified-name walking — a wrong callback
|
|
39
|
+
* edge is worse than none.
|
|
40
|
+
*/
|
|
41
|
+
export declare function matchFunctionRef(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
12
42
|
/**
|
|
13
43
|
* Try to resolve a reference by exact name match
|
|
14
44
|
*/
|
|
@@ -17,6 +47,37 @@ export declare function matchByExactName(ref: UnresolvedRef, context: Resolution
|
|
|
17
47
|
* Try to resolve by qualified name
|
|
18
48
|
*/
|
|
19
49
|
export declare function matchByQualifiedName(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a C++ chained call whose receiver is itself a call — encoded by the
|
|
52
|
+
* extractor as `<innerCallee>().<method>` (#645). The receiver's type is what
|
|
53
|
+
* the inner call returns; the outer method is then resolved and VALIDATED on it
|
|
54
|
+
* (resolveMethodOnType requires `cls::method` to exist), so a wrong inference
|
|
55
|
+
* produces no edge rather than a wrong one.
|
|
56
|
+
*/
|
|
57
|
+
export declare function matchCppCallChain(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a `::`-scoped factory chain whose receiver is a scoped/static call —
|
|
60
|
+
* PHP `Cls::for($x)->method()` (#608, the per-credential Laravel client idiom) or
|
|
61
|
+
* Rust `Foo::new().bar()` (an associated-function call) — both encoded by the
|
|
62
|
+
* extractor as `Cls::factory().method`. The receiver's type is what `Cls::factory`
|
|
63
|
+
* returns: a `self` marker (PHP `: self`/`: static`, Rust `-> Self`) resolves to
|
|
64
|
+
* the factory's own type, a concrete return type to that type. The outer method is
|
|
65
|
+
* then resolved and VALIDATED on it (resolveMethodOnType requires the method to
|
|
66
|
+
* exist on the type or a supertype it conforms to), so a wrong inference yields no
|
|
67
|
+
* edge rather than a wrong one. Shared by the `::`-receiver languages (PHP, Rust).
|
|
68
|
+
*/
|
|
69
|
+
export declare function matchScopedCallChain(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a dotted chained call whose receiver is a static factory / fluent call —
|
|
72
|
+
* `Foo.getInstance().bar()`, encoded by the extractor as `Foo.getInstance().bar`
|
|
73
|
+
* (#645/#608 mechanism). The receiver's type is what `Foo.getInstance` returns
|
|
74
|
+
* (its declared return type); the outer method is then resolved and VALIDATED on
|
|
75
|
+
* it (resolveMethodOnType requires `Type::method` to exist), so a wrong inference
|
|
76
|
+
* yields no edge rather than a wrong one (e.g. a same-named `bar()` on an
|
|
77
|
+
* unrelated class is never matched). Shared by the dot-notation languages
|
|
78
|
+
* (Java, Kotlin, C#, Swift) — same receiver shape, same `Class::method` qualified names.
|
|
79
|
+
*/
|
|
80
|
+
export declare function matchDottedCallChain(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null;
|
|
20
81
|
/**
|
|
21
82
|
* Try to resolve by method name on a class/object
|
|
22
83
|
*/
|