circle-ir 3.31.0 → 3.33.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.
@@ -0,0 +1,555 @@
1
+ /**
2
+ * Runtime-registration extractor (issue #15 — Phases 1 + 2).
3
+ *
4
+ * Recognises framework registration patterns where a handler is wired into a
5
+ * dispatch table at module-load time. Static call extraction sees the
6
+ * registration call/decorator but not the edge from registrar → handler.
7
+ *
8
+ * Downstream consumers (e.g. dead-code reachability) read
9
+ * `ir.runtime_registrations` and add each resolved handler as a virtual entry
10
+ * root, eliminating "unreachable" false positives for framework handlers.
11
+ *
12
+ * Phase 1 — JS/TS Express-family (shipped 3.32.0):
13
+ * - HTTP routes: `app.METHOD(path?, ...handlers)` for METHOD ∈ HTTP_VERBS
14
+ * - Middleware: `app.use(...handlers)`
15
+ * - Event listeners: `emitter.on('event', handler)` on express-shaped receivers
16
+ *
17
+ * Phase 2 — Python decorators (3.33.0):
18
+ * - Every `@decorator` on a function emits a registration with handler =
19
+ * decorated function. Known frameworks are tagged (flask, fastapi,
20
+ * django, click, pytest, celery, numba); built-in (property,
21
+ * staticmethod, etc.) is tagged `stdlib`. Routing-style decorators
22
+ * (`@app.route`, `@app.get`, `@router.post`) are classified as
23
+ * `kind: 'http_route'` so downstream consumers can treat JS routes and
24
+ * Python routes uniformly.
25
+ *
26
+ * Out of scope (Phase 3):
27
+ * - Rust trait dispatch (`impl Trait for Type`, `Box<dyn Trait>`,
28
+ * `inventory::submit!`, `linkme::distributed_slice`).
29
+ * - Subapp mounting (`app.use('/api', subApp)`) handler resolution.
30
+ */
31
+ import { getNodeText, getNodesFromCache } from '../parser.js';
32
+ /** HTTP verb methods recognised on Express-family routers. */
33
+ const HTTP_VERB_METHODS = new Set([
34
+ 'get', 'post', 'put', 'patch', 'delete',
35
+ 'head', 'options', 'all',
36
+ ]);
37
+ /** Middleware registration methods. */
38
+ const MIDDLEWARE_METHODS = new Set(['use']);
39
+ /** Event-listener methods (Node EventEmitter / WebSocket-style). */
40
+ const EVENT_LISTENER_METHODS = new Set(['on', 'once', 'ws']);
41
+ /** Receivers heuristically treated as express-family routers. */
42
+ const EXPRESS_RECEIVER_NAMES = new Set([
43
+ 'app', 'router', 'server', 'apiRouter',
44
+ // common framework instances
45
+ 'fastify', 'koa', 'express',
46
+ ]);
47
+ /** Module specifiers that, when imported, signal an Express-family framework. */
48
+ const FRAMEWORK_MODULE_PATTERNS = [
49
+ /^express$/, /^@?fastify(\/.*)?$/, /^koa$/, /^restify$/, /^hapi$/,
50
+ /^@nestjs\/common$/, /^@nestjs\/core$/,
51
+ ];
52
+ /**
53
+ * Extract runtime-registration patterns from a parsed file.
54
+ *
55
+ * Phase 1 covers JavaScript/TypeScript. Phase 2 adds Python decorators.
56
+ * Returns `[]` for any other language.
57
+ */
58
+ export function extractRuntimeRegistrations(tree, cache, language, imports) {
59
+ if (language === 'javascript' || language === 'typescript') {
60
+ return extractJSRuntimeRegistrations(tree, cache, imports);
61
+ }
62
+ if (language === 'python') {
63
+ return extractPythonRuntimeRegistrations(tree, cache, imports);
64
+ }
65
+ return [];
66
+ }
67
+ function buildHandlerIndex(tree, cache, imports) {
68
+ const decls = new Map();
69
+ const recordDeclaration = (name, node) => {
70
+ if (!decls.has(name)) {
71
+ decls.set(name, {
72
+ line: node.startPosition.row + 1,
73
+ column: node.startPosition.column,
74
+ });
75
+ }
76
+ };
77
+ // function foo() {...}
78
+ for (const fn of getNodesFromCache(tree.rootNode, 'function_declaration', cache)) {
79
+ const nameNode = fn.childForFieldName('name');
80
+ if (nameNode)
81
+ recordDeclaration(getNodeText(nameNode), fn);
82
+ }
83
+ // const foo = (...) => ... ; const foo = function () { ... }
84
+ const collectVarDeclarators = (parentType) => {
85
+ for (const decl of getNodesFromCache(tree.rootNode, parentType, cache)) {
86
+ for (let i = 0; i < decl.childCount; i++) {
87
+ const child = decl.child(i);
88
+ if (!child || child.type !== 'variable_declarator')
89
+ continue;
90
+ const nameNode = child.childForFieldName('name');
91
+ const valueNode = child.childForFieldName('value');
92
+ if (!nameNode || !valueNode)
93
+ continue;
94
+ if (valueNode.type === 'arrow_function' ||
95
+ valueNode.type === 'function_expression' ||
96
+ valueNode.type === 'function') {
97
+ recordDeclaration(getNodeText(nameNode), child);
98
+ }
99
+ }
100
+ }
101
+ };
102
+ collectVarDeclarators('lexical_declaration');
103
+ collectVarDeclarators('variable_declaration');
104
+ let hasFrameworkImport = false;
105
+ if (imports) {
106
+ for (const imp of imports) {
107
+ const mod = imp.from_package ?? '';
108
+ if (mod && FRAMEWORK_MODULE_PATTERNS.some(re => re.test(mod))) {
109
+ hasFrameworkImport = true;
110
+ break;
111
+ }
112
+ }
113
+ }
114
+ return { declarations: decls, hasFrameworkImport };
115
+ }
116
+ function extractJSRuntimeRegistrations(tree, cache, imports) {
117
+ const out = [];
118
+ const index = buildHandlerIndex(tree, cache, imports);
119
+ const callExpressions = getNodesFromCache(tree.rootNode, 'call_expression', cache);
120
+ for (const call of callExpressions) {
121
+ const fnNode = call.childForFieldName('function');
122
+ if (!fnNode || fnNode.type !== 'member_expression')
123
+ continue;
124
+ const objectNode = fnNode.childForFieldName('object');
125
+ const propertyNode = fnNode.childForFieldName('property');
126
+ if (!objectNode || !propertyNode)
127
+ continue;
128
+ const method = getNodeText(propertyNode);
129
+ const receiver = getNodeText(objectNode);
130
+ const kind = classifyMethod(method);
131
+ if (!kind)
132
+ continue;
133
+ // Receiver filtering: keep noise out. Either:
134
+ // - the receiver name is a known router-ish identifier, OR
135
+ // - a framework module is imported (relaxed: any member call with the
136
+ // right method shape is considered).
137
+ if (!isExpressShapedReceiver(receiver) && !index.hasFrameworkImport) {
138
+ continue;
139
+ }
140
+ const argsNode = call.childForFieldName('arguments');
141
+ if (!argsNode)
142
+ continue;
143
+ const argNodes = getRealArgs(argsNode);
144
+ if (argNodes.length === 0)
145
+ continue;
146
+ // Path (literal first argument) is optional. Determine arg slice for handlers.
147
+ let path;
148
+ let handlerStart = 0;
149
+ const first = argNodes[0];
150
+ if (first.type === 'string') {
151
+ path = stripQuotes(getNodeText(first));
152
+ handlerStart = 1;
153
+ }
154
+ else if (first.type === 'template_string' && !hasTemplateSubstitution(first)) {
155
+ path = stripBackticks(getNodeText(first));
156
+ handlerStart = 1;
157
+ }
158
+ // For `.use(handler)` / `.on('event', handler)` / `.get('/p', h1, h2)` etc.
159
+ // Every remaining positional argument that is a function-like is a handler.
160
+ for (let i = handlerStart; i < argNodes.length; i++) {
161
+ const handlerNode = argNodes[i];
162
+ const handler = resolveHandler(handlerNode, index);
163
+ if (!handler)
164
+ continue;
165
+ out.push({
166
+ kind,
167
+ framework: inferFramework(receiver, index.hasFrameworkImport),
168
+ registrar: {
169
+ method,
170
+ receiver,
171
+ line: call.startPosition.row + 1,
172
+ column: call.startPosition.column,
173
+ },
174
+ ...(path !== undefined ? { path } : {}),
175
+ handler,
176
+ });
177
+ }
178
+ }
179
+ return out;
180
+ }
181
+ function classifyMethod(method) {
182
+ if (HTTP_VERB_METHODS.has(method))
183
+ return 'http_route';
184
+ if (MIDDLEWARE_METHODS.has(method))
185
+ return 'middleware';
186
+ if (EVENT_LISTENER_METHODS.has(method))
187
+ return 'event_listener';
188
+ return null;
189
+ }
190
+ function isExpressShapedReceiver(receiver) {
191
+ if (EXPRESS_RECEIVER_NAMES.has(receiver))
192
+ return true;
193
+ // Common naming: `apiRouter`, `userRouter`, `<x>Router`, `<x>App`
194
+ if (/(?:Router|App|Server)$/.test(receiver))
195
+ return true;
196
+ return false;
197
+ }
198
+ function inferFramework(receiver, hasFrameworkImport) {
199
+ if (receiver === 'fastify')
200
+ return 'fastify';
201
+ if (receiver === 'koa')
202
+ return 'koa';
203
+ if (receiver === 'express')
204
+ return 'express';
205
+ // Default heuristic: known express-shaped receivers default to express when
206
+ // a framework import is present; otherwise unknown.
207
+ return hasFrameworkImport ? 'express' : 'unknown';
208
+ }
209
+ /** Skip punctuation children inside `arguments` */
210
+ function getRealArgs(argsNode) {
211
+ const out = [];
212
+ for (let i = 0; i < argsNode.childCount; i++) {
213
+ const child = argsNode.child(i);
214
+ if (!child)
215
+ continue;
216
+ if (child.type === '(' || child.type === ')' || child.type === ',')
217
+ continue;
218
+ out.push(child);
219
+ }
220
+ return out;
221
+ }
222
+ function stripQuotes(s) {
223
+ if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
224
+ return s.slice(1, -1);
225
+ }
226
+ return s;
227
+ }
228
+ function stripBackticks(s) {
229
+ if (s.length >= 2 && s[0] === '`' && s[s.length - 1] === '`') {
230
+ return s.slice(1, -1);
231
+ }
232
+ return s;
233
+ }
234
+ function hasTemplateSubstitution(node) {
235
+ for (let i = 0; i < node.childCount; i++) {
236
+ const child = node.child(i);
237
+ if (child && child.type === 'template_substitution')
238
+ return true;
239
+ }
240
+ return false;
241
+ }
242
+ function resolveHandler(node, index) {
243
+ // Inline arrow / function expression — name=null, location is the lambda site.
244
+ if (node.type === 'arrow_function' ||
245
+ node.type === 'function_expression' ||
246
+ node.type === 'function') {
247
+ return {
248
+ name: null,
249
+ line: node.startPosition.row + 1,
250
+ column: node.startPosition.column,
251
+ };
252
+ }
253
+ // Named identifier — look up declaration site if available, else use call site.
254
+ if (node.type === 'identifier') {
255
+ const name = getNodeText(node);
256
+ const decl = index.declarations.get(name);
257
+ if (decl) {
258
+ return { name, line: decl.line, column: decl.column };
259
+ }
260
+ return {
261
+ name,
262
+ line: node.startPosition.row + 1,
263
+ column: node.startPosition.column,
264
+ };
265
+ }
266
+ // Member expression (e.g. controller.handle) — record the textual reference.
267
+ if (node.type === 'member_expression') {
268
+ return {
269
+ name: getNodeText(node),
270
+ line: node.startPosition.row + 1,
271
+ column: node.startPosition.column,
272
+ };
273
+ }
274
+ // Anything else (object literals, complex expressions): not a handler.
275
+ return null;
276
+ }
277
+ // =============================================================================
278
+ // Python — Phase 2
279
+ // =============================================================================
280
+ /** HTTP-route decorator method names (after the dotted prefix). */
281
+ const PY_HTTP_ROUTE_METHODS = new Set([
282
+ // Flask/Blueprint: app.route, blueprint.route, api.route
283
+ 'route',
284
+ // FastAPI / Starlette / DRF method-specific
285
+ 'get', 'post', 'put', 'patch', 'delete', 'head', 'options',
286
+ // Flask aliases (Flask 2.x): app.get/post/...
287
+ ]);
288
+ /** Flask middleware-style decorators. */
289
+ const PY_MIDDLEWARE_METHODS = new Set([
290
+ 'before_request', 'after_request', 'teardown_request',
291
+ 'before_first_request', 'teardown_appcontext',
292
+ // Starlette / FastAPI
293
+ 'middleware',
294
+ ]);
295
+ /** Event/lifecycle-style decorators. */
296
+ const PY_EVENT_METHODS = new Set([
297
+ 'errorhandler', 'on_event', 'exception_handler',
298
+ // Celery beat etc — not strictly events but lifecycle
299
+ ]);
300
+ /** Python stdlib / built-in decorators that don't register externally. */
301
+ const PY_STDLIB_DECORATORS = new Set([
302
+ 'property', 'staticmethod', 'classmethod', 'abstractmethod', 'cached_property',
303
+ 'dataclass', 'cache', 'lru_cache', 'singledispatch', 'singledispatchmethod',
304
+ 'contextmanager', 'asynccontextmanager', 'final', 'override',
305
+ 'wraps',
306
+ ]);
307
+ function summarisePythonImports(imports) {
308
+ const s = {
309
+ hasFlask: false, hasFastApi: false, hasCelery: false,
310
+ hasNumba: false, hasClick: false, hasPytest: false,
311
+ };
312
+ if (!imports)
313
+ return s;
314
+ for (const imp of imports) {
315
+ const mod = imp.from_package ?? '';
316
+ if (!mod)
317
+ continue;
318
+ if (/^flask(\b|\.)/.test(mod))
319
+ s.hasFlask = true;
320
+ if (/^fastapi(\b|\.)/.test(mod) || /^starlette(\b|\.)/.test(mod))
321
+ s.hasFastApi = true;
322
+ if (/^celery(\b|\.)/.test(mod))
323
+ s.hasCelery = true;
324
+ if (/^numba(\b|\.)/.test(mod))
325
+ s.hasNumba = true;
326
+ if (/^click(\b|\.)/.test(mod))
327
+ s.hasClick = true;
328
+ if (/^pytest(\b|\.)/.test(mod))
329
+ s.hasPytest = true;
330
+ }
331
+ return s;
332
+ }
333
+ function extractPythonRuntimeRegistrations(tree, cache, imports) {
334
+ const out = [];
335
+ const importSummary = summarisePythonImports(imports);
336
+ const decoratedDefs = getNodesFromCache(tree.rootNode, 'decorated_definition', cache);
337
+ for (const dd of decoratedDefs) {
338
+ // Find the function_definition child (skip class_definition for now —
339
+ // class-level decorators are not the dead-code use case).
340
+ let fnNode = null;
341
+ const decorators = [];
342
+ for (let i = 0; i < dd.childCount; i++) {
343
+ const child = dd.child(i);
344
+ if (!child)
345
+ continue;
346
+ if (child.type === 'decorator') {
347
+ decorators.push(child);
348
+ }
349
+ else if (child.type === 'function_definition' || child.type === 'async_function_definition') {
350
+ fnNode = child;
351
+ }
352
+ }
353
+ if (!fnNode || decorators.length === 0)
354
+ continue;
355
+ const handler = pythonHandlerFromFunctionDef(fnNode);
356
+ if (!handler)
357
+ continue;
358
+ for (const dec of decorators) {
359
+ const parsed = parsePythonDecorator(dec);
360
+ if (!parsed)
361
+ continue;
362
+ const { receiver, method, path, line, column } = parsed;
363
+ const { kind, framework } = classifyPythonDecorator(receiver, method, importSummary);
364
+ out.push({
365
+ kind,
366
+ framework,
367
+ registrar: { method, receiver, line, column },
368
+ ...(path !== undefined ? { path } : {}),
369
+ handler,
370
+ });
371
+ }
372
+ }
373
+ return out;
374
+ }
375
+ function pythonHandlerFromFunctionDef(fn) {
376
+ const nameNode = fn.childForFieldName('name');
377
+ if (!nameNode)
378
+ return null;
379
+ return {
380
+ name: getNodeText(nameNode),
381
+ line: fn.startPosition.row + 1,
382
+ column: fn.startPosition.column,
383
+ };
384
+ }
385
+ /**
386
+ * Parse a `decorator` node into receiver/method/path components.
387
+ * The decorator wraps one of: `identifier`, `attribute`, or `call`.
388
+ */
389
+ function parsePythonDecorator(dec) {
390
+ // Skip the leading `@` token; take the first non-trivial child.
391
+ let target = null;
392
+ for (let i = 0; i < dec.childCount; i++) {
393
+ const child = dec.child(i);
394
+ if (!child || child.type === '@')
395
+ continue;
396
+ target = child;
397
+ break;
398
+ }
399
+ if (!target)
400
+ return null;
401
+ const line = dec.startPosition.row + 1;
402
+ const column = dec.startPosition.column;
403
+ // @bare_decorator
404
+ if (target.type === 'identifier') {
405
+ return { receiver: '', method: getNodeText(target), line, column };
406
+ }
407
+ // @pkg.attr (no call)
408
+ if (target.type === 'attribute') {
409
+ const { receiver, method } = splitDottedAttribute(target);
410
+ return { receiver, method, line, column };
411
+ }
412
+ // @pkg.attr(...) or @bare_decorator(...)
413
+ if (target.type === 'call') {
414
+ const fnNode = target.childForFieldName('function');
415
+ if (!fnNode)
416
+ return null;
417
+ let receiver = '';
418
+ let method = '';
419
+ if (fnNode.type === 'identifier') {
420
+ method = getNodeText(fnNode);
421
+ }
422
+ else if (fnNode.type === 'attribute') {
423
+ const split = splitDottedAttribute(fnNode);
424
+ receiver = split.receiver;
425
+ method = split.method;
426
+ }
427
+ else {
428
+ // Complex expression like `make_decorator()(...)` — record textual.
429
+ method = getNodeText(fnNode);
430
+ }
431
+ // Look at first positional arg for a literal string path.
432
+ const path = extractFirstStringArg(target);
433
+ return { receiver, method, path, line, column };
434
+ }
435
+ return null;
436
+ }
437
+ /** Split `a.b.c` into receiver=`a.b`, method=`c`. */
438
+ function splitDottedAttribute(attr) {
439
+ const objectNode = attr.childForFieldName('object');
440
+ const attrNode = attr.childForFieldName('attribute');
441
+ const method = attrNode ? getNodeText(attrNode) : '';
442
+ const receiver = objectNode ? getNodeText(objectNode) : '';
443
+ return { receiver, method };
444
+ }
445
+ /** Extract first positional argument as a literal string if present. */
446
+ function extractFirstStringArg(call) {
447
+ const argsNode = call.childForFieldName('arguments');
448
+ if (!argsNode)
449
+ return undefined;
450
+ for (let i = 0; i < argsNode.childCount; i++) {
451
+ const child = argsNode.child(i);
452
+ if (!child)
453
+ continue;
454
+ if (child.type === '(' || child.type === ')' || child.type === ',')
455
+ continue;
456
+ // First real argument
457
+ if (child.type === 'string') {
458
+ return stripPythonStringQuotes(getNodeText(child));
459
+ }
460
+ // Anything else as first positional arg → no path
461
+ return undefined;
462
+ }
463
+ return undefined;
464
+ }
465
+ function stripPythonStringQuotes(s) {
466
+ // Handle prefixes like b'', r'', u'', f'' — we don't need their semantics here.
467
+ const m = s.match(/^[bBrRuUfF]{0,2}(['"])(.*)\1$/s);
468
+ if (m)
469
+ return m[2];
470
+ if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
471
+ return s.slice(1, -1);
472
+ }
473
+ return s;
474
+ }
475
+ /**
476
+ * Classify a Python decorator into kind + framework.
477
+ *
478
+ * The classification cascade:
479
+ * 1. stdlib built-in (property, staticmethod, ...) → kind=decorator, framework=stdlib
480
+ * 2. `@<framework>.<method>` where framework is recognised
481
+ * 3. `@app.<http_verb>` / `@router.<http_verb>` / `@app.route` → http_route
482
+ * 4. Middleware / event hooks on Flask-like receivers
483
+ * 5. Generic decorator → kind=decorator, framework=unknown
484
+ */
485
+ function classifyPythonDecorator(receiver, method, imp) {
486
+ // 1. stdlib built-ins (bare decorators, e.g. @property)
487
+ if (!receiver && PY_STDLIB_DECORATORS.has(method)) {
488
+ return { kind: 'decorator', framework: 'stdlib' };
489
+ }
490
+ // 2. Framework-prefixed decorators
491
+ if (receiver) {
492
+ const head = receiver.split('.')[0];
493
+ // pytest.fixture / pytest.mark.parametrize
494
+ if (head === 'pytest') {
495
+ return { kind: 'decorator', framework: 'pytest' };
496
+ }
497
+ if (head === 'click') {
498
+ return { kind: 'decorator', framework: 'click' };
499
+ }
500
+ if (head === 'numba' || head === 'nb') {
501
+ return { kind: 'decorator', framework: 'numba' };
502
+ }
503
+ if (head === 'celery') {
504
+ return { kind: 'decorator', framework: 'celery' };
505
+ }
506
+ }
507
+ // 3. HTTP-route decorators on app/router/blueprint/api receivers
508
+ if (receiver && PY_HTTP_ROUTE_METHODS.has(method)) {
509
+ const isRoutey = isPyRouterReceiver(receiver);
510
+ if (isRoutey) {
511
+ // Framework inference: import-driven
512
+ let framework = 'unknown';
513
+ if (imp.hasFlask)
514
+ framework = 'flask';
515
+ else if (imp.hasFastApi)
516
+ framework = 'fastapi';
517
+ else if (method === 'route')
518
+ framework = 'flask'; // Flask hallmark
519
+ else
520
+ framework = 'fastapi'; // verbs alone bias to FastAPI
521
+ return { kind: 'http_route', framework };
522
+ }
523
+ }
524
+ // 4. Middleware-style decorators
525
+ if (receiver && PY_MIDDLEWARE_METHODS.has(method)) {
526
+ return { kind: 'middleware', framework: imp.hasFlask ? 'flask' : (imp.hasFastApi ? 'fastapi' : 'unknown') };
527
+ }
528
+ // 5. Event-style decorators
529
+ if (receiver && PY_EVENT_METHODS.has(method)) {
530
+ return { kind: 'event_listener', framework: imp.hasFlask ? 'flask' : (imp.hasFastApi ? 'fastapi' : 'unknown') };
531
+ }
532
+ // 6. app.task / @<x>.task — celery if celery imported
533
+ if (method === 'task' && imp.hasCelery) {
534
+ return { kind: 'decorator', framework: 'celery' };
535
+ }
536
+ // 7. Django auth/method decorators (bare)
537
+ if (!receiver && (method === 'login_required' || method === 'require_http_methods' || method === 'api_view')) {
538
+ return { kind: 'decorator', framework: 'django' };
539
+ }
540
+ // Fallthrough
541
+ return { kind: 'decorator', framework: 'unknown' };
542
+ }
543
+ /** Names commonly used for Flask/FastAPI app/router/blueprint instances. */
544
+ function isPyRouterReceiver(receiver) {
545
+ const head = receiver.split('.')[0];
546
+ if (!head)
547
+ return false;
548
+ if (['app', 'router', 'blueprint', 'bp', 'api', 'application'].includes(head))
549
+ return true;
550
+ // Suffix conventions: my_router, user_bp, etc.
551
+ if (/_(router|bp|blueprint|app|api)$/.test(head))
552
+ return true;
553
+ return false;
554
+ }
555
+ //# sourceMappingURL=runtime-registrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-registrations.js","sourceRoot":"","sources":["../../../src/core/extractors/runtime-registrations.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,5 @@
2
2
  * Core module index - re-exports parser and extractors
3
3
  */
4
4
  export { initParser, loadLanguage, createParser, createFreshParser, parse, disposeTree, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, getNodesFromCache, isInitialized, isLanguageLoaded, resetParser, type SupportedLanguage, type SyntaxNode, type Node, type NodeCache, type Language, type Tree, } from './parser.js';
5
- export { extractMeta, extractTypes, extractCalls, extractImports, extractExports, buildCFG, buildDFG, } from './extractors/index.js';
5
+ export { extractMeta, extractTypes, extractCalls, extractImports, extractExports, buildCFG, buildDFG, extractRuntimeRegistrations, } from './extractors/index.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,IAAI,GACV,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,IAAI,EACT,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,IAAI,GACV,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC"}
@@ -4,5 +4,5 @@
4
4
  // Parser
5
5
  export { initParser, loadLanguage, createParser, createFreshParser, parse, disposeTree, walkTree, findNodes, findAncestor, getNodeText, collectAllNodes, getNodesFromCache, isInitialized, isLanguageLoaded, resetParser, } from './parser.js';
6
6
  // Extractors
7
- export { extractMeta, extractTypes, extractCalls, extractImports, extractExports, buildCFG, buildDFG, } from './extractors/index.js';
7
+ export { extractMeta, extractTypes, extractCalls, extractImports, extractExports, buildCFG, buildDFG, extractRuntimeRegistrations, } from './extractors/index.js';
8
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,GAOZ,MAAM,aAAa,CAAC;AAErB,aAAa;AACb,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,GACT,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,OAAO,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,WAAW,GAOZ,MAAM,aAAa,CAAC;AAErB,aAAa;AACb,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC"}
@@ -513,6 +513,45 @@ export interface CircleIR {
513
513
  findings?: SastFinding[];
514
514
  /** Software metrics computed by metric passes (CK suite, Halstead, etc.). */
515
515
  metrics?: FileMetrics;
516
+ /**
517
+ * Runtime registration patterns (HTTP routes, middlewares, event listeners)
518
+ * that establish call-graph edges not visible in the static AST.
519
+ *
520
+ * Phase 1 (issue #15) covers JS/TS Express-family route registration.
521
+ * Consumers (e.g. cognium-ai dead-code) treat `handler` targets as virtual
522
+ * entry roots when computing reachability.
523
+ */
524
+ runtime_registrations?: RuntimeRegistration[];
525
+ }
526
+ /**
527
+ * A runtime registration recording that a handler is wired into a framework
528
+ * dispatch table at module-load time. See issue #15.
529
+ */
530
+ export interface RuntimeRegistration {
531
+ kind: 'http_route' | 'middleware' | 'event_listener' | 'decorator';
532
+ framework?: 'express' | 'fastify' | 'koa' | 'nestjs' | 'flask' | 'fastapi' | 'django' | 'click' | 'pytest' | 'celery' | 'numba' | 'stdlib' | 'unknown';
533
+ /**
534
+ * The registration call site itself.
535
+ * - JS Phase 1: `app.get(...)`, `router.use(...)`, `server.on(...)` — receiver
536
+ * is the runtime object, method is the verb.
537
+ * - Python Phase 2: a `@receiver.method` decorator — receiver is everything
538
+ * before the last dotted segment (empty string for bare `@name`),
539
+ * method is the last segment.
540
+ */
541
+ registrar: {
542
+ method: string;
543
+ receiver: string;
544
+ line: number;
545
+ column: number;
546
+ };
547
+ /** Literal route path or event name when the leading argument is a string literal. */
548
+ path?: string;
549
+ /** Resolved handler. `name === null` for inline arrow / function expression. */
550
+ handler: {
551
+ name: string | null;
552
+ line: number;
553
+ column: number;
554
+ };
516
555
  }
517
556
  export interface AnalysisResponse {
518
557
  success: boolean;