@aroman22/codegraph-vba 1.15.0 → 1.17.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 +131 -3
- package/dist/bin/daemon-release.d.ts +7 -0
- package/dist/db/queries.d.ts +41 -0
- package/dist/extraction/access-erd-extractor.d.ts +57 -0
- package/dist/extraction/extraction-version.d.ts +1 -1
- package/dist/extraction/grammars.d.ts +20 -0
- package/dist/extraction/index.d.ts +1 -0
- package/dist/extraction/parse-pool.d.ts +8 -3
- package/dist/extraction/sql-query-extractor.d.ts +16 -14
- package/dist/extraction/sql-table-scan.d.ts +184 -0
- package/dist/extraction/tree-sitter.d.ts +10 -1
- package/dist/extraction/vba/call-sweep.d.ts +2 -7
- package/dist/extraction/vba/calls.d.ts +24 -4
- package/dist/extraction/vba/constants.d.ts +7 -14
- package/dist/extraction/vba/context.d.ts +443 -7
- package/dist/extraction/vba/controls.d.ts +18 -1
- package/dist/extraction/vba/declarations.d.ts +1 -6
- package/dist/extraction/vba/dims.d.ts +11 -7
- package/dist/extraction/vba/docmd.d.ts +29 -2
- package/dist/extraction/vba/enums-consts.d.ts +7 -14
- package/dist/extraction/vba/error-channel.d.ts +57 -0
- package/dist/extraction/vba/errors.d.ts +64 -0
- package/dist/extraction/vba/filesystem-statements.d.ts +23 -0
- package/dist/extraction/vba/implements.d.ts +1 -6
- package/dist/extraction/vba/labels.d.ts +26 -0
- package/dist/extraction/vba/module-vars.d.ts +36 -0
- package/dist/extraction/vba/options.d.ts +88 -0
- package/dist/extraction/vba/parameters.d.ts +35 -0
- package/dist/extraction/vba/procedures.d.ts +1 -9
- package/dist/extraction/vba/rules.d.ts +10 -5
- package/dist/extraction/vba/runtime-objects.d.ts +59 -0
- package/dist/extraction/vba/signature.d.ts +57 -0
- package/dist/extraction/vba/sql-wrapper.d.ts +76 -3
- package/dist/extraction/vba/text-utils.d.ts +62 -2
- package/dist/extraction/vba-extractor.d.ts +18 -1
- package/dist/extraction/vba-form-extractor.d.ts +28 -14
- package/dist/extraction/vba-preprocess.d.ts +89 -3
- package/dist/extraction/vba-source.d.ts +0 -10
- package/dist/extraction/vba-test-manifest-extractor.d.ts +0 -6
- package/dist/graph/behavior-evidence.d.ts +162 -0
- package/dist/index.d.ts +22 -0
- package/dist/mcp/daemon-paths.d.ts +6 -0
- package/dist/mcp/daemon-registry.d.ts +82 -7
- package/dist/mcp/daemon-watchdog.d.ts +12 -0
- package/dist/mcp/daemon.d.ts +20 -1
- package/dist/mcp/proxy.d.ts +32 -0
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/tools.d.ts +12 -0
- package/dist/project-config.d.ts +43 -2
- package/dist/resolution/index.d.ts +47 -2
- package/dist/resolution/name-matcher.d.ts +25 -0
- package/dist/resolution/vba-runtime-objects.d.ts +11 -11
- package/dist/types.d.ts +13 -5
- package/dist/utils/backtrace-helpers.d.ts +14 -2
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -382,7 +382,10 @@ The two are **sibling tools**: Dysflow owns the Access binary round-trip (sync,
|
|
|
382
382
|
|
|
383
383
|
| Pattern | `.bas` / `.cls` side | `.form.txt` / `.report.txt` side | How |
|
|
384
384
|
|---|---|---|---|
|
|
385
|
-
| **Form code ↔ UI binding** | `.cls` class node (canonical form code) |
|
|
385
|
+
| **Form code ↔ UI binding** | `.cls` class node (canonical form code) | `form-layout` / `report-layout` node + one `form-instance-control` per named control (and a `property` node per control *type*) | `UnresolvedReference` with `synthesizedBy: 'vba-form-binding'`; resolver wires the layout → sibling `.cls` class at index time |
|
|
386
|
+
| **Control event handler** (`btnSave_Click`) | `.cls` handler procedure | `form-instance-control` node for `btnSave` | `event-handler` edge stored **handler → control**. To go the other way — from a control to what runs on it — follow that edge *backwards* |
|
|
387
|
+
| **Form / report lifecycle event** (`Form_Load`, `Report_Open`) | `.cls` handler procedure | `form-layout` / `report-layout` node | `event-handler` edge **handler → layout**, carrying `metadata.scope: 'form'` so it is distinguishable from a control handler |
|
|
388
|
+
| **Expression-wired event** (`OnClick ="=AuditNow()"`) | `.bas`/`.cls` procedure named in the expression | `form-instance-control` / layout node carrying the property | Resolves to the **same** `event-handler` direction (handler → control), tagged `synthesizedBy: 'vba-expression-handler'`. A bare macro name or `[Event Procedure]` emits nothing rather than inventing a procedure |
|
|
386
389
|
| **`Implements IFoo`** | `.cls` declares `Implements IFoo` | — | Emits an `implements` edge from the class to `IFoo` |
|
|
387
390
|
| **`Dim x As Foo.Bar`** | `.bas`/`.cls` qualified type reference | — | `references` edge to `Foo` with `synthesizedBy: 'vba-name-resolution'`; silent when unresolvable |
|
|
388
391
|
| **`WithEvents m_X As Form_Foo`** | `.cls` listener declaration | — | `references` edge to `Form_Foo` with `synthesizedBy: 'vba-withevents'` — closes the event-driven form flow |
|
|
@@ -396,7 +399,11 @@ The two are **sibling tools**: Dysflow owns the Access binary round-trip (sync,
|
|
|
396
399
|
|
|
397
400
|
**Hard invariants** enforced by the extractor and verified by tests:
|
|
398
401
|
|
|
399
|
-
- **`.cls` is the canonical source for form code.** `.form.txt`
|
|
402
|
+
- **`.cls` is the canonical source for form code.** `.form.txt` / `.report.txt` emit **zero procedures** — no `function` / `sub` node, and no class node for the form's own code, ever comes from a layout file. What they do emit is the `form-layout` / `report-layout` container, one `form-instance-control` per named control, a `property` node per control *type*, and a synthetic placeholder node for each table or query the layout binds through `RecordSource` / `RowSource` / `ControlSource`. Dysflow overwrites the layout file's embedded code on the next import, so emitting procedures from there would be both wrong and ephemeral.
|
|
403
|
+
- **An event binding is stored in one direction: handler → control/layout.** There is no reverse edge and no bidirectional edge. Reaching a handler from its control means following the `event-handler` edge backwards; that is what `traverseGraph` and `getBehaviorEvidence` do for you.
|
|
404
|
+
- **A control belongs to the layout that `contains` it**, not to whatever file its name appears in. The same control name (`btnSave`) routinely exists on several forms, so any lookup by name must be scoped by layout — an unscoped name is ambiguous, not a match.
|
|
405
|
+
- **A call is not always a `calls` edge.** VBA's statement-form Sub call (`SaveRecord` alone on a line) could also be a `Const` read, so the extractor keeps it as an ambiguous identifier and it resolves to a `references` edge onto the procedure. Consumers that follow only `calls` lose the dominant call style in Access code-behind.
|
|
406
|
+
- **CodeGraph indexes the exported source tree, not the live `.accdb`.** Everything here is static evidence: it does not prove a handler ran, and it says nothing about whether the binary matches the export — Dysflow owns that round-trip. Edges tagged `provenance: 'heuristic'` are inferred from naming and string contents; absence of an edge is missing evidence, never proof of no runtime effect.
|
|
400
407
|
- **Option-only files stay silent.** A `.bas` containing only `Option ...` directives emits zero symbol nodes; a `.bas` with only `Enum`, `Const`, `Event`, `Type`, or `Declare` declarations DOES emit its module node because those declarations are real graph symbols.
|
|
401
408
|
|
|
402
409
|
**VBA / Access node kinds added by the fork:**
|
|
@@ -414,6 +421,125 @@ The two are **sibling tools**: Dysflow owns the Access binary round-trip (sync,
|
|
|
414
421
|
|
|
415
422
|
**Scope:** Dysflow-managed projects only (Dysflow's `.form.txt` / `.report.txt` SaveAsText format). Legacy `.frm` / `.dsr` Access binary formats are not in scope.
|
|
416
423
|
|
|
424
|
+
### Semantic acceptance
|
|
425
|
+
|
|
426
|
+
Extraction tests prove the graph holds what it should; this proves the
|
|
427
|
+
**answers** are right — which expected paths and entities are missing, and
|
|
428
|
+
which unrelated ones get reported. Node and edge counts detect neither.
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
npm run acceptance:vba
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
It builds a fresh, isolated index over a throwaway copy of
|
|
435
|
+
`__tests__/fixtures/vba-consumer-semantics/`, asks the public consumer surfaces
|
|
436
|
+
the questions in `__tests__/fixtures/vba-consumer-semantics-ground-truth.json`
|
|
437
|
+
— expected answers read off the source by hand, each with its source location,
|
|
438
|
+
each carrying what must be present **and** what must not — compares them, and
|
|
439
|
+
exits non-zero on the first missing or unexpected identity. It also runs on the
|
|
440
|
+
normal test and CI path; no separate workflow hosts it.
|
|
441
|
+
|
|
442
|
+
To evaluate an authorized copy of your own export with the same criteria and
|
|
443
|
+
harness, write a ground-truth file in the same shape and point the run at both:
|
|
444
|
+
|
|
445
|
+
```bash
|
|
446
|
+
VBA_ACCEPTANCE_CORPUS=/path/to/export-copy VBA_ACCEPTANCE_GROUND_TRUTH=/path/to/ground-truth.json npm run acceptance:vba
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
The run is local: it reads only the directory you name, copies it to a
|
|
450
|
+
temporary directory it deletes afterwards, never touches an `.accdb`, never
|
|
451
|
+
discovers projects on your machine, and keeps your paths out of the report it
|
|
452
|
+
prints. Keep a ground-truth file derived from private data beside the export
|
|
453
|
+
copy — don't commit it. Passing the checked-in corpus is not certification of
|
|
454
|
+
arbitrary projects, and says nothing about live Access execution.
|
|
455
|
+
|
|
456
|
+
### Worked example: from a control to the tables it touches
|
|
457
|
+
|
|
458
|
+
Runnable against any indexed Dysflow export. It is also executed as a test —
|
|
459
|
+
`documented Access traversal example matches indexed fixture` in
|
|
460
|
+
`__tests__/vba-documented-example.test.ts` — against the checked-in
|
|
461
|
+
`__tests__/fixtures/vba-consumer-semantics/` corpus, so these values are
|
|
462
|
+
asserted, not illustrative.
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
import CodeGraph from 'codegraph-vba';
|
|
466
|
+
|
|
467
|
+
const cg = await CodeGraph.open('/path/to/dysflow-export');
|
|
468
|
+
|
|
469
|
+
// 1. Resolve the control WITH its layout. `btnSave` exists on several forms,
|
|
470
|
+
// so the layout file is what makes the answer unambiguous. A bare name is
|
|
471
|
+
// ambiguous, not a match.
|
|
472
|
+
const btnSave = cg
|
|
473
|
+
.searchNodes('btnSave', { kinds: ['form-instance-control'], languages: ['vba'] })
|
|
474
|
+
.map(({ node }) => node)
|
|
475
|
+
.find((node) => node.filePath.endsWith('Form_Orders.form.txt'))!;
|
|
476
|
+
|
|
477
|
+
// 2. The binding is stored handler -> control, so the handler is found by
|
|
478
|
+
// following it BACKWARDS.
|
|
479
|
+
const binding = cg
|
|
480
|
+
.getIncomingEdges(btnSave.id)
|
|
481
|
+
.filter((edge) => edge.kind === 'event-handler');
|
|
482
|
+
// binding[0].metadata.eventName === 'Click'
|
|
483
|
+
// binding[0].source === the btnSave_Click node's id
|
|
484
|
+
|
|
485
|
+
// 3. What runs, and what it reaches. One read, already scoped by step 1.
|
|
486
|
+
const behavior = cg.getBehaviorEvidence({ nodeId: btnSave.id });
|
|
487
|
+
// behavior.evidence[0].handler === 'btnSave_Click'
|
|
488
|
+
// behavior.evidence[0].callPath === ['btnSave_Click', 'SaveOrderTotals']
|
|
489
|
+
// behavior.evidence[0].tables === ['tblOrderLines', 'tblProducts']
|
|
490
|
+
|
|
491
|
+
// 4. The tables are reached THROUGH the saved query — the context says which,
|
|
492
|
+
// instead of leaving you to match names yourself.
|
|
493
|
+
behavior.context.data.find((d) => d.name === 'tblOrderLines')!.throughQuery;
|
|
494
|
+
// 'qryOrderTotals'
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Same control name on a different form, same call, different answer:
|
|
498
|
+
`{ name: 'btnSave', layout: 'Form_Invoices' }` returns
|
|
499
|
+
`['btnSave_Click', 'SaveInvoiceTotals']` — and `{ name: 'btnSave' }` with no
|
|
500
|
+
layout returns no evidence at all, listing both candidates in
|
|
501
|
+
`context.ambiguous`.
|
|
502
|
+
|
|
503
|
+
### Behavior evidence for one control
|
|
504
|
+
|
|
505
|
+
`getBehaviorEvidence` answers "what does this control actually do?" in one
|
|
506
|
+
read, for a consumer that wants data rather than prose: the event binding, the
|
|
507
|
+
call paths under it, and the tables and effects those procedures reach.
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
const evidence = cg.getBehaviorEvidence({ name: 'btnSave', layout: 'Form_Orders' });
|
|
511
|
+
|
|
512
|
+
evidence.evidence;
|
|
513
|
+
// [{ handler: 'btnSave_Click',
|
|
514
|
+
// callPath: ['btnSave_Click', 'SaveOrderTotals'],
|
|
515
|
+
// tables: ['tblOrderLines', 'tblProducts'],
|
|
516
|
+
// effects: ['data-access:qryOrderTotals', 'data-access:tblOrderLines', 'data-access:tblProducts'] }]
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
- **Identify the target by `nodeId`** whenever you have one. A `name` needs a
|
|
520
|
+
`layout` as soon as it is not unique — the same control name usually exists on
|
|
521
|
+
several forms, and an ambiguous name is **refused** with the candidates listed
|
|
522
|
+
in `context.ambiguous`, never narrowed to an arbitrary match.
|
|
523
|
+
- **`callPath` is one root-to-leaf path**, handler first. Distinct branches are
|
|
524
|
+
separate entries, never concatenated into a sequence the runtime would not
|
|
525
|
+
take; a path that re-enters a procedure ends there.
|
|
526
|
+
- **`effects` uses a closed vocabulary**: `read:<name>`, `write:<name>`,
|
|
527
|
+
`data-access:<name>` (direction unknown — neither a read nor a write),
|
|
528
|
+
`opens-form:<Name>`, `opens-report:<Name>`, `raises-event:<Name>`.
|
|
529
|
+
- **`context` carries everything that is not the payload**: node identities and
|
|
530
|
+
source locations, how each handler is wired (`control`, `form` lifecycle,
|
|
531
|
+
`expression`), what could not be resolved, and whether a depth or result
|
|
532
|
+
budget cut the answer short (`maxCallDepth` defaults to 5, `maxResults` to 50).
|
|
533
|
+
- **It is static evidence from exported source.** An empty `tables` or `effects`
|
|
534
|
+
list means the index holds no such fact — **not** that the code has no runtime
|
|
535
|
+
effect. It also says nothing about whether the `.accdb` binary matches the
|
|
536
|
+
export.
|
|
537
|
+
|
|
538
|
+
The same assembler is available over MCP as `codegraph_behavior_evidence`
|
|
539
|
+
(unlisted by default like the other narrow tools — enable it with
|
|
540
|
+
`CODEGRAPH_MCP_TOOLS=explore,behavior_evidence`), returning the identical
|
|
541
|
+
payload as JSON.
|
|
542
|
+
|
|
417
543
|
---
|
|
418
544
|
|
|
419
545
|
## Quick Start
|
|
@@ -616,7 +742,7 @@ When running as an MCP server, CodeGraph exposes a **single tool** — `codegrap
|
|
|
616
742
|
|------|---------|
|
|
617
743
|
| `codegraph_explore` | Answer almost any question in one call — "how does X work", a flow ("how does X reach Y"), or surveying an area — returning the relevant symbols' verbatim source grouped by file, plus the call paths between them and a blast-radius summary. Surfaces dynamic-dispatch hops (callbacks, React re-render, interface→impl) grep can't follow. Name a file or symbol in the query to read its current line-numbered source, the same shape the Read tool gives you. |
|
|
618
744
|
|
|
619
|
-
The other tools (`codegraph_node`, `codegraph_search`, `codegraph_callers`, `codegraph_callees`, `codegraph_impact`, `codegraph_files`, `codegraph_status`) stay fully functional but **unlisted by default** — everything they return already arrives inline on `codegraph_explore` (its blast-radius section, the relationship map, a symbol's body as its callee list). Re-enable any of them for the MCP surface with the `CODEGRAPH_MCP_TOOLS` environment variable (e.g. `CODEGRAPH_MCP_TOOLS=explore,node,search,callers`), or use their CLI equivalents (`codegraph-vba node` / `query` / `callers` / `callees` / `impact` / `files` / `status`).
|
|
745
|
+
The other tools (`codegraph_node`, `codegraph_search`, `codegraph_callers`, `codegraph_callees`, `codegraph_impact`, `codegraph_files`, `codegraph_status`, and the Access-specific `codegraph_behavior_evidence`) stay fully functional but **unlisted by default** — everything they return already arrives inline on `codegraph_explore` (its blast-radius section, the relationship map, a symbol's body as its callee list). Re-enable any of them for the MCP surface with the `CODEGRAPH_MCP_TOOLS` environment variable (e.g. `CODEGRAPH_MCP_TOOLS=explore,node,search,callers`), or use their CLI equivalents (`codegraph-vba node` / `query` / `callers` / `callees` / `impact` / `files` / `status`).
|
|
620
746
|
|
|
621
747
|
Even when the server's own root has no `.codegraph-vba/` index, the tools stay available: pass `projectPath` to query any indexed project — a sub-service in a monorepo, or a second repo — in the same session. A path that has no index returns clean guidance to use built-in tools instead, so nothing fails loudly, and indexing stays your decision.
|
|
622
748
|
|
|
@@ -644,6 +770,8 @@ const results = cg.searchNodes('UserService');
|
|
|
644
770
|
const callers = cg.getCallers(results[0].node.id);
|
|
645
771
|
const context = await cg.buildContext('fix login bug', { maxNodes: 20, includeCode: true, format: 'markdown' });
|
|
646
772
|
const impact = cg.getImpactRadius(results[0].node.id, 2);
|
|
773
|
+
// Access/VBA only — see "Behavior evidence for one control" above:
|
|
774
|
+
const behavior = cg.getBehaviorEvidence({ name: 'btnSave', layout: 'Form_Orders' });
|
|
647
775
|
|
|
648
776
|
cg.watch(); // auto-sync on file changes
|
|
649
777
|
cg.unwatch(); // stop watching
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { type StopResult } from '../mcp/daemon-registry';
|
|
3
|
+
/** Testable command handler behind `daemon stop --path`. */
|
|
4
|
+
export declare function runDaemonStop(root: string, release?: (path: string) => Promise<StopResult>): Promise<string>;
|
|
5
|
+
/** Register the non-interactive parser path without importing the full CLI entrypoint. */
|
|
6
|
+
export declare function registerDaemonStopCommand(parent: Command, run?: (path: string) => Promise<string>, output?: (value: string) => void): Command;
|
|
7
|
+
//# sourceMappingURL=daemon-release.d.ts.map
|
package/dist/db/queries.d.ts
CHANGED
|
@@ -330,8 +330,38 @@ export declare class QueryBuilder {
|
|
|
330
330
|
* module. These synthetic nodes are created by the extractor for
|
|
331
331
|
* cross-file type references (`Dim x As MyEnum`) but may not have been
|
|
332
332
|
* resolved to the real type node during the main resolution pass.
|
|
333
|
+
*
|
|
334
|
+
* Issue #257: `type_of` counts too. A `parameter` node typed `As Cliente`
|
|
335
|
+
* points at the very same stub, and a stub reached ONLY that way (the file
|
|
336
|
+
* declares no `Dim … As Cliente`) must still be discoverable — otherwise it
|
|
337
|
+
* is never repointed and the parameter's type stays unresolved forever.
|
|
333
338
|
*/
|
|
334
339
|
getVbaReferenceStubs(): Node[];
|
|
340
|
+
/**
|
|
341
|
+
* Table nodes declared by an Access structure export (#257, half B).
|
|
342
|
+
*
|
|
343
|
+
* These are `class` nodes stamped `metadata.synthesizedBy =
|
|
344
|
+
* 'access-erd-table'` by `AccessErdExtractor`. They are the ONLY table nodes
|
|
345
|
+
* in the graph that carry real column information, which is what makes them
|
|
346
|
+
* the canonical target `resolveAccessErdTableNodes` promotes the SQL-derived
|
|
347
|
+
* placeholders onto.
|
|
348
|
+
*
|
|
349
|
+
* They are also excluded from `getVbaReferenceStubs` above: an ERD table is
|
|
350
|
+
* a declaration, not a stub, and letting the stub resolver repoint it onto a
|
|
351
|
+
* same-named VBA class would delete it along with all of its field nodes.
|
|
352
|
+
*/
|
|
353
|
+
getAccessErdTableNodes(): Node[];
|
|
354
|
+
/**
|
|
355
|
+
* Synthetic table placeholders recovered from SQL text (#257, half B) — the
|
|
356
|
+
* `class` nodes that `vba/sql-wrapper.ts` and `sql-query-extractor.ts` emit
|
|
357
|
+
* as the target of a table `references` edge. They carry a name and nothing
|
|
358
|
+
* else, and are keyed on the REFERENCING file, so the same table named from
|
|
359
|
+
* three modules is three unrelated nodes.
|
|
360
|
+
*
|
|
361
|
+
* Returned so `resolveAccessErdTableNodes` can repoint their incoming
|
|
362
|
+
* references onto the one ERD declaration that actually has the columns.
|
|
363
|
+
*/
|
|
364
|
+
getSqlTablePlaceholders(): Node[];
|
|
335
365
|
/**
|
|
336
366
|
* Repoint an edge's `target` + `metadata` in place, leaving all other
|
|
337
367
|
* columns (source, kind, line, col, provenance) untouched. Used by
|
|
@@ -477,6 +507,17 @@ export declare class QueryBuilder {
|
|
|
477
507
|
* Get unresolved references by name (for resolution)
|
|
478
508
|
*/
|
|
479
509
|
getUnresolvedByName(name: string): UnresolvedReference[];
|
|
510
|
+
/**
|
|
511
|
+
* Get the unresolved references recorded for one file, ordered by position.
|
|
512
|
+
*
|
|
513
|
+
* Scoped read for consumers that report what could NOT be answered about a
|
|
514
|
+
* specific procedure (issue #299): loading every row to filter in memory
|
|
515
|
+
* would scale with the whole project instead of the file being explained.
|
|
516
|
+
* Both pending and failed rows are returned — for this purpose "the
|
|
517
|
+
* resolver never matched it" and "the resolver has not tried yet" are the
|
|
518
|
+
* same honest answer: the index cannot say.
|
|
519
|
+
*/
|
|
520
|
+
getUnresolvedReferencesForFile(filePath: string): UnresolvedReference[];
|
|
480
521
|
/**
|
|
481
522
|
* Get all unresolved references
|
|
482
523
|
*/
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ExtractionResult } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* `metadata.synthesizedBy` stamped on every table node this extractor emits.
|
|
4
|
+
* The resolution pass keys on it to tell an ERD DECLARATION apart from a SQL
|
|
5
|
+
* placeholder that merely mentions the same name.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ERD_TABLE_SYNTHESIZED_BY = "access-erd-table";
|
|
8
|
+
/**
|
|
9
|
+
* `metadata.synthesizedBy` stamped on the `references` edge from a linked table
|
|
10
|
+
* to the external backend file it lives in.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately NOT `vba-external-backend` (#256's tag): the NODE shape is
|
|
13
|
+
* shared with #256 — a `file` node keyed on the normalized path with
|
|
14
|
+
* `metadata.external` — but the mechanism that discovered it differs (a linked
|
|
15
|
+
* table's connection string here, a query's `IN "<path>"` clause there), and
|
|
16
|
+
* the tag is what tells the two apart in the graph.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ERD_LINKED_TABLE_SYNTHESIZED_BY = "vba-linked-table";
|
|
19
|
+
/**
|
|
20
|
+
* Content-shape gate: is `source` a generated Access structure export — i.e.
|
|
21
|
+
* does its FIRST non-empty line open with `# Estructura de Datos:`?
|
|
22
|
+
*
|
|
23
|
+
* Pure and exported so the gate is testable on its own; the path match is
|
|
24
|
+
* applied separately by `isAccessErdFile` in `grammars.ts`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isAccessErdShape(source: string): boolean;
|
|
27
|
+
export declare class AccessErdExtractor {
|
|
28
|
+
private filePath;
|
|
29
|
+
private source;
|
|
30
|
+
private nodes;
|
|
31
|
+
private edges;
|
|
32
|
+
private errors;
|
|
33
|
+
constructor(filePath: string, source: string);
|
|
34
|
+
extract(): ExtractionResult;
|
|
35
|
+
private parse;
|
|
36
|
+
/**
|
|
37
|
+
* Open (or reuse) the table node for a `## Tabla:` header. The node id is
|
|
38
|
+
* line-independent so a name declared twice in one document collapses onto
|
|
39
|
+
* one node instead of two half-populated ones.
|
|
40
|
+
*/
|
|
41
|
+
private openTable;
|
|
42
|
+
/**
|
|
43
|
+
* A `(LINKED)` marker opens a short blockquote block naming the origin table
|
|
44
|
+
* and the connection string. Read forward over the contiguous `>` lines,
|
|
45
|
+
* flag the table, and — when the connection string names a database FILE —
|
|
46
|
+
* emit the external-backend node plus the `references` edge to it.
|
|
47
|
+
*/
|
|
48
|
+
private markLinked;
|
|
49
|
+
/**
|
|
50
|
+
* A `| Campo | Tipo | Longitud |` data row becomes one `type_member` node
|
|
51
|
+
* `contains`-ed by its table. The markdown header row and the `:---`
|
|
52
|
+
* separator row are not fields.
|
|
53
|
+
*/
|
|
54
|
+
private maybeAddField;
|
|
55
|
+
private createFileNode;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=access-erd-extractor.d.ts.map
|
|
@@ -21,5 +21,5 @@
|
|
|
21
21
|
* turns the re-index hint into noise — keep it honest (see CLAUDE.md, "Honesty
|
|
22
22
|
* in the product is load-bearing").
|
|
23
23
|
*/
|
|
24
|
-
export declare const EXTRACTION_VERSION =
|
|
24
|
+
export declare const EXTRACTION_VERSION = 27;
|
|
25
25
|
//# sourceMappingURL=extraction-version.d.ts.map
|
|
@@ -89,6 +89,26 @@ export declare function isVbaTestManifestFile(filePath: string): boolean;
|
|
|
89
89
|
* from this extractor even if a future file slips into the same directory.
|
|
90
90
|
*/
|
|
91
91
|
export declare function isVbaTestSequenceFile(filePath: string): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Access structure export: a markdown file sitting DIRECTLY inside an `ERD/`
|
|
94
|
+
* directory (`ERD/Estructura_Datos.md`, `src/backend/ERD/Estructura_Datos.md`).
|
|
95
|
+
* Issue #257.
|
|
96
|
+
*
|
|
97
|
+
* `.md` is deliberately NOT in `EXTENSION_MAP` (ordinary markdown is not
|
|
98
|
+
* indexed); this is the sole gate that makes such a document an indexable
|
|
99
|
+
* source file, mirroring the `.sql`/`queries.json` gate for
|
|
100
|
+
* `SqlQueryExtractor`.
|
|
101
|
+
*
|
|
102
|
+
* `ERD` is a very ordinary folder name, so this path match is only HALF the
|
|
103
|
+
* routing decision: `AccessErdExtractor` additionally requires the document's
|
|
104
|
+
* first non-empty line to be the generated export's `# Estructura de Datos:`
|
|
105
|
+
* header, and emits nothing at all when it is not. A hand-written diagram in a
|
|
106
|
+
* non-Access repo therefore contributes no nodes, no edges and no errors.
|
|
107
|
+
*
|
|
108
|
+
* Only files directly in the directory match — `ERD/notes/deep.md` does not —
|
|
109
|
+
* because the generator writes one flat document per backend.
|
|
110
|
+
*/
|
|
111
|
+
export declare function isAccessErdFile(filePath: string): boolean;
|
|
92
112
|
/**
|
|
93
113
|
* Initialize the tree-sitter WASM runtime. Must be called before loading grammars.
|
|
94
114
|
* Does NOT load any grammar WASM files — use loadGrammarsForLanguages() for that.
|
|
@@ -228,5 +228,6 @@ export declare class ExtractionOrchestrator {
|
|
|
228
228
|
};
|
|
229
229
|
}
|
|
230
230
|
export { extractFromSource } from './tree-sitter';
|
|
231
|
+
export type { VbaExtractionOptions } from './vba/options';
|
|
231
232
|
export { detectLanguage, isSourceFile, isLanguageSupported, isGrammarLoaded, getSupportedLanguages, initGrammars, loadGrammarsForLanguages, loadAllGrammars } from './grammars';
|
|
232
233
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* the default is capped and the env var lets constrained machines dial it down.
|
|
28
28
|
*/
|
|
29
29
|
import type { Language, ExtractionResult } from '../types';
|
|
30
|
+
import type { VbaExtractionOptions } from './vba/options';
|
|
30
31
|
/**
|
|
31
32
|
* Minimal worker surface the pool drives — satisfied by a real `worker_threads`
|
|
32
33
|
* Worker. Abstracted so tests can inject a fake worker and exercise the pool's
|
|
@@ -47,9 +48,13 @@ export interface ParseTask {
|
|
|
47
48
|
content: string;
|
|
48
49
|
language: Language;
|
|
49
50
|
frameworkNames?: string[];
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Issue #243: every VBA-specific extraction knob in ONE structured-cloneable
|
|
53
|
+
* object (previously the separate `vbaTargets` / `maxRaiseFanout` fields).
|
|
54
|
+
* It crosses the worker boundary via `postMessage`, so it must stay plain
|
|
55
|
+
* data — see the contract in `./vba/options`.
|
|
56
|
+
*/
|
|
57
|
+
vbaOptions?: VbaExtractionOptions;
|
|
53
58
|
/**
|
|
54
59
|
* Issue #154 — gate the 3 Dysflow-specific VBA sub-extractors. `true`
|
|
55
60
|
* (the default) keeps the pre-refactor behavior; `false` opts out so
|
|
@@ -6,20 +6,6 @@ export declare class SqlQueryExtractor {
|
|
|
6
6
|
private edges;
|
|
7
7
|
private errors;
|
|
8
8
|
constructor(filePath: string, source: string);
|
|
9
|
-
/**
|
|
10
|
-
* Table name following `FROM` / `JOIN` / `INTO` / `UPDATE`. Captures an optional
|
|
11
|
-
* bracketed/unbracketed schema prefix followed by `.`, so `FROM dbo.tblCustomers`
|
|
12
|
-
* and `FROM [My Schema].[My Table]` come through as one composite reference.
|
|
13
|
-
* Without the prefix the regex still matches a single identifier (bracketed
|
|
14
|
-
* or bare) byte-identical to the old shape. `\p{L}` covers accented identifiers
|
|
15
|
-
* common in localized schemas.
|
|
16
|
-
*
|
|
17
|
-
* The captured composite goes to `sweepTables`, which strips ALL brackets
|
|
18
|
-
* (including internal ones in the bracketed-schema case) — so the public
|
|
19
|
-
* node name is the unwrapped form `dbo.tblCustomers` / `My Schema.My Table`,
|
|
20
|
-
* matching how plain `[Order Details]` is also unwrapped to `Order Details`.
|
|
21
|
-
*/
|
|
22
|
-
private static readonly TABLE_RE;
|
|
23
9
|
extract(): ExtractionResult;
|
|
24
10
|
private basenameWithoutExt;
|
|
25
11
|
private createFileNode;
|
|
@@ -27,7 +13,23 @@ export declare class SqlQueryExtractor {
|
|
|
27
13
|
* Scan the SQL for table names and emit one synthetic `class` node + one
|
|
28
14
|
* `references` edge per distinct table. The table node id is line-independent
|
|
29
15
|
* (line 0) so the same table referenced N times collapses to one node.
|
|
16
|
+
*
|
|
17
|
+
* Issue #203: delegates to the shared `scanSqlTables` scanner in
|
|
18
|
+
* `src/extraction/sql-table-scan.ts` so a SQL reserved word can never
|
|
19
|
+
* be emitted as a table name — `WHERE x=1`, `ORDER BY a`, `SET a=1`
|
|
20
|
+
* never become phantom `class` nodes here.
|
|
30
21
|
*/
|
|
31
22
|
private sweepTables;
|
|
23
|
+
/**
|
|
24
|
+
* Issue #256 — a saved query can read from another database file via the
|
|
25
|
+
* Access `IN "<path>"` clause. Emit one `file`-kind node per distinct
|
|
26
|
+
* external backend (keyed on the normalized path, so the same file named
|
|
27
|
+
* from two different queries converges on ONE node) plus a `references`
|
|
28
|
+
* edge from this query, tagged `vba-external-backend`.
|
|
29
|
+
*
|
|
30
|
+
* `scanSqlExternalBackends` already de-duplicates within one query, so no
|
|
31
|
+
* local `seen` set is needed here.
|
|
32
|
+
*/
|
|
33
|
+
private sweepExternalBackends;
|
|
32
34
|
}
|
|
33
35
|
//# sourceMappingURL=sql-query-extractor.d.ts.map
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # SQL table-name scanner — leaf module shared by every VBA + SQL
|
|
3
|
+
* table-extraction path (Issue #203).
|
|
4
|
+
*
|
|
5
|
+
* Before this module existed, the same `FROM/JOIN/INTO/UPDATE` capture
|
|
6
|
+
* regex lived in three places:
|
|
7
|
+
*
|
|
8
|
+
* - `src/extraction/sql-query-extractor.ts:57` (saved queries)
|
|
9
|
+
* - `src/extraction/vba/sql-wrapper.ts:80-81` (in-code SQL sweep)
|
|
10
|
+
* - `src/extraction/vba-form-extractor.ts:617-618` (RecordSource/RowSource)
|
|
11
|
+
*
|
|
12
|
+
* The three copies had already started to diverge (`vba-form-extractor`
|
|
13
|
+
* grew a `SQL_PREFIX_RE` the other two never adopted), and every
|
|
14
|
+
* caller was vulnerable to the same silently-wrong captures the issue
|
|
15
|
+
* lists:
|
|
16
|
+
*
|
|
17
|
+
* ```vba
|
|
18
|
+
* getdb().Execute "DELETE FROM " & tabla & " WHERE activo = 1"
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Today, `collectSqlWrapperChain` silently drops non-literal operands
|
|
22
|
+
* (variables, function calls) and joins surviving literal fragments
|
|
23
|
+
* with a space. The dropped operand leaves a whitespace gap that
|
|
24
|
+
* `\s+` happily crosses, so `DELETE FROM ` + ` ` + ` WHERE activo = 1`
|
|
25
|
+
* becomes `DELETE FROM WHERE activo = 1` — and `SQL_TABLE_RE`
|
|
26
|
+
* captures `WHERE` as a table reference.
|
|
27
|
+
*
|
|
28
|
+
* ## What this module guarantees
|
|
29
|
+
*
|
|
30
|
+
* 1. The shared regex (with optional schema prefix + bracketed
|
|
31
|
+
* identifiers, identical bytes to the old shape) lives in ONE
|
|
32
|
+
* place.
|
|
33
|
+
* 2. `SQL_RESERVED_TABLE_TOKENS` rejects every SQL reserved word that
|
|
34
|
+
* can legitimately appear immediately after a
|
|
35
|
+
* `FROM`/`JOIN`/`INTO`/`UPDATE` keyword in a real statement —
|
|
36
|
+
* `WHERE`, `ORDER`, `GROUP`, `HAVING`, `SET`, `VALUES`, `SELECT`,
|
|
37
|
+
* `INNER`, `LEFT`, `RIGHT`, `OUTER`, `FULL`, `CROSS`, `JOIN`,
|
|
38
|
+
* `ON`, `UNION`, `AS`, `DISTINCT`, `TOP`, `IN`, `EXISTS`. The list
|
|
39
|
+
* is exhaustive for the SQL grammar subset codegraph models.
|
|
40
|
+
* 3. `scanSqlTables` reads a SINGLE joined SQL string. It does NOT
|
|
41
|
+
* know about VBA concatenation — the JOIN-WITH-SPACE shape
|
|
42
|
+
* `collectSqlWrapperChain` produces is its input contract.
|
|
43
|
+
* Operands dropped by `collectSqlWrapperChain` are now replaced
|
|
44
|
+
* with a `?` sentinel (see `vba/sql-wrapper.ts`); the reserved-
|
|
45
|
+
* word reject list catches any `?` keyword bridge the concat could
|
|
46
|
+
* still create.
|
|
47
|
+
* 4. Each row carries the SQL `clause` (`FROM`/`JOIN`/`INTO`/`UPDATE`)
|
|
48
|
+
* so callers can classify `access: 'read' | 'write'` without
|
|
49
|
+
* re-running the SQL classifier.
|
|
50
|
+
*
|
|
51
|
+
* ## Issue #256 — DDL verbs and the Access `IN` clause
|
|
52
|
+
*
|
|
53
|
+
* The clause set also covers `CREATE TABLE`, `ALTER TABLE` and
|
|
54
|
+
* `DROP TABLE`; all three target a table they mutate, so they carry
|
|
55
|
+
* `access: 'write'`. The reserved-word reject list applies to them
|
|
56
|
+
* unchanged.
|
|
57
|
+
*
|
|
58
|
+
* Separately, `scanSqlExternalBackends` captures the Access-specific
|
|
59
|
+
* `IN "<path>"` clause, which points a query at ANOTHER database file.
|
|
60
|
+
* That operand is a file, not a table, so it gets its own scanner and
|
|
61
|
+
* its own node shape (`buildExternalBackendNode`) rather than being
|
|
62
|
+
* folded into the table rows.
|
|
63
|
+
*
|
|
64
|
+
* ## Defense in depth
|
|
65
|
+
*
|
|
66
|
+
* The reserved-word check uses the **unwrapped first identifier
|
|
67
|
+
* component** so schema-qualified inputs like `FROM WHERE.ID` are also
|
|
68
|
+
* rejected (the unwrapped form is `WHERE.ID`, first component is
|
|
69
|
+
* `WHERE`). The check is case-insensitive (SQL keywords are
|
|
70
|
+
* case-insensitive by spec).
|
|
71
|
+
*
|
|
72
|
+
* Returning `[]` for a reserved-word capture is the "silent beats
|
|
73
|
+
* wrong" doctrine the project documents in `CLAUDE.md`: emitting a
|
|
74
|
+
* confident wrong edge ("WHERE is a table that gets written to")
|
|
75
|
+
* pollutes downstream queries far more than emitting no edge at all.
|
|
76
|
+
*/
|
|
77
|
+
import { Node } from '../types';
|
|
78
|
+
export interface SqlTableScanRow {
|
|
79
|
+
/** The unwrapped table name (brackets + surrounding whitespace stripped). */
|
|
80
|
+
table: string;
|
|
81
|
+
/**
|
|
82
|
+
* The SQL clause that introduced the reference. The four DML clauses
|
|
83
|
+
* (`FROM`/`JOIN`/`INTO`/`UPDATE`) were the original set; Issue #256
|
|
84
|
+
* added the three DDL verbs, whose targets are always writes.
|
|
85
|
+
*/
|
|
86
|
+
clause: SqlTableClause;
|
|
87
|
+
/** Whether this row reads or mutates the table — derived from the SQL verb. */
|
|
88
|
+
access: 'read' | 'write';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Every clause keyword the scanner captures a table name after. The DDL
|
|
92
|
+
* three are two-word keywords normalized to a single interior space
|
|
93
|
+
* (`create table` → `CREATE TABLE`).
|
|
94
|
+
*/
|
|
95
|
+
export type SqlTableClause = 'FROM' | 'JOIN' | 'INTO' | 'UPDATE' | 'CREATE TABLE' | 'ALTER TABLE' | 'DROP TABLE';
|
|
96
|
+
/**
|
|
97
|
+
* Canonical reject list — every SQL reserved word that can appear
|
|
98
|
+
* immediately after `FROM`/`JOIN`/`INTO`/`UPDATE` in a real statement.
|
|
99
|
+
* The list is exported so consumers can introspect it; it is also the
|
|
100
|
+
* authoritative source the scanner consults internally.
|
|
101
|
+
*
|
|
102
|
+
* The list intentionally omits `FROM`/`JOIN`/`INTO`/`UPDATE` itself
|
|
103
|
+
* (those are the capturing keywords) and `ALL` / `ANY` (they are
|
|
104
|
+
* legitimate table-ish tokens in some dialects but rarely appear as
|
|
105
|
+
* the first token after a FROM-style keyword in a well-formed
|
|
106
|
+
* statement).
|
|
107
|
+
*/
|
|
108
|
+
export declare const SQL_RESERVED_TABLE_TOKENS: ReadonlySet<string>;
|
|
109
|
+
/**
|
|
110
|
+
* Scan a SQL string for `FROM` / `JOIN` / `INTO` / `UPDATE` table
|
|
111
|
+
* references. Returns one row per match; the caller is responsible
|
|
112
|
+
* for cross-row deduplication if it wants one node per table.
|
|
113
|
+
*
|
|
114
|
+
* Captures that resolve to a SQL reserved word (Issue #203 — e.g.
|
|
115
|
+
* `FROM WHERE x=1` → `WHERE`) are DROPPED. This encodes
|
|
116
|
+
* "we don't know this table" rather than guessing — matching the
|
|
117
|
+
* "silent beats wrong" / "partial coverage is worse than none"
|
|
118
|
+
* doctrine the project documents in `CLAUDE.md`.
|
|
119
|
+
*
|
|
120
|
+
* Schema-qualified inputs (`FROM WHERE.ID` → `WHERE.ID`) are also
|
|
121
|
+
* dropped: the check inspects the FIRST unwrapped identifier
|
|
122
|
+
* component (everything up to the first `.`), case-insensitive.
|
|
123
|
+
*
|
|
124
|
+
* Empty / whitespace-only / non-DML input returns `[]`.
|
|
125
|
+
*/
|
|
126
|
+
export declare function scanSqlTables(sql: string): SqlTableScanRow[];
|
|
127
|
+
/**
|
|
128
|
+
* Issue #256: the `synthesizedBy` tag stamped on every `references`
|
|
129
|
+
* edge that points at an external backend file. Exported so consumers
|
|
130
|
+
* and tests share one spelling.
|
|
131
|
+
*/
|
|
132
|
+
export declare const EXTERNAL_BACKEND_SYNTHESIZED_BY = "vba-external-backend";
|
|
133
|
+
/**
|
|
134
|
+
* Issue #256: normalize an external-database path so the SAME file named
|
|
135
|
+
* from two different queries converges on ONE node.
|
|
136
|
+
*
|
|
137
|
+
* Access backends are Windows paths: the separator may be `\` or `/`,
|
|
138
|
+
* the case is not significant, and a hand-written path often carries a
|
|
139
|
+
* doubled separator or a trailing one. Normalizing to lowercase
|
|
140
|
+
* forward-slash form makes `C:\Datos\Otra.accdb` and
|
|
141
|
+
* `c:/datos/otra.accdb` the same key.
|
|
142
|
+
*
|
|
143
|
+
* A leading `//` is preserved so a UNC share (`\\SERVIDOR\Datos\x.accdb`)
|
|
144
|
+
* stays distinguishable from an absolute local path.
|
|
145
|
+
*
|
|
146
|
+
* Returns `''` for blank input; callers drop empty paths.
|
|
147
|
+
*/
|
|
148
|
+
export declare function normalizeBackendPath(raw: string): string;
|
|
149
|
+
/**
|
|
150
|
+
* Issue #256: scan a SQL string for Access `IN "<path>"` external-backend
|
|
151
|
+
* clauses. Returns the NORMALIZED paths in first-appearance order, with
|
|
152
|
+
* duplicates collapsed (two spellings of the same file are one entry).
|
|
153
|
+
*
|
|
154
|
+
* Empty / unquoted / value-list `IN` operands yield nothing — the same
|
|
155
|
+
* "silent beats wrong" doctrine the table scanner follows: an operand we
|
|
156
|
+
* cannot key on produces no node rather than a guessed one.
|
|
157
|
+
*/
|
|
158
|
+
export declare function scanSqlExternalBackends(sql: string): string[];
|
|
159
|
+
/**
|
|
160
|
+
* Issue #256: build the graph node for an external backend file.
|
|
161
|
+
*
|
|
162
|
+
* `file` is the honest kind — it IS a file, just not one this index
|
|
163
|
+
* parsed — so no new `NodeKind` is needed, and `metadata.external`
|
|
164
|
+
* keeps it distinguishable from indexed files in every query.
|
|
165
|
+
*
|
|
166
|
+
* Two properties matter and are both deliberate:
|
|
167
|
+
*
|
|
168
|
+
* 1. **Convergence.** The node id is keyed on the normalized path via a
|
|
169
|
+
* synthetic `synthetic:external-db/<path>` file path (the same trick
|
|
170
|
+
* `vba/tempvars.ts` uses for TempVars keys), so the same backend named
|
|
171
|
+
* from two different queries — or from a saved query AND from in-code
|
|
172
|
+
* SQL — collapses to ONE node instead of one per referencing file.
|
|
173
|
+
* 2. **Byte-identity.** Everything on the node derives from the
|
|
174
|
+
* normalized path alone: no line, no column, no per-caller language.
|
|
175
|
+
* Every emitter therefore produces an identical node, so whichever
|
|
176
|
+
* one is written last cannot silently rewrite the others' fields.
|
|
177
|
+
* Per-site position lives on the `references` EDGE, which is where
|
|
178
|
+
* call-site information belongs.
|
|
179
|
+
*
|
|
180
|
+
* The `language` is pinned to `vba` because the node models an Access
|
|
181
|
+
* database file, whichever extractor happened to discover it.
|
|
182
|
+
*/
|
|
183
|
+
export declare function buildExternalBackendNode(normalizedPath: string): Node;
|
|
184
|
+
//# sourceMappingURL=sql-table-scan.d.ts.map
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Handles parsing source code and extracting structural information.
|
|
5
5
|
*/
|
|
6
6
|
import { Language, ExtractionResult } from '../types';
|
|
7
|
+
import type { VbaExtractionOptions } from './vba/options';
|
|
7
8
|
export { generateNodeId } from './tree-sitter-helpers';
|
|
8
9
|
/**
|
|
9
10
|
* TreeSitterExtractor - Main extraction class
|
|
@@ -709,6 +710,14 @@ export declare class TreeSitterExtractor {
|
|
|
709
710
|
* just a `file` node. Read from `codegraph.json` via
|
|
710
711
|
* `loadDysflowExportConfig(rootDir)` at the call site and threaded in here
|
|
711
712
|
* so this function stays project-config-agnostic.
|
|
713
|
+
*
|
|
714
|
+
* `vbaOptions` (issue #243) is the object form of every VBA-specific knob and
|
|
715
|
+
* is what in-repo callers pass. The `vbaTargets` / `maxRaiseFanout`
|
|
716
|
+
* positionals are `@deprecated` and kept for one release; when both are
|
|
717
|
+
* supplied the OBJECT WINS per field.
|
|
718
|
+
*
|
|
719
|
+
* @param vbaTargets @deprecated Pass `vbaOptions.targets` instead.
|
|
720
|
+
* @param maxRaiseFanout @deprecated Pass `vbaOptions.maxRaiseFanout` instead.
|
|
712
721
|
*/
|
|
713
|
-
export declare function extractFromSource(filePath: string, source: string, language?: Language, frameworkNames?: string[], vbaTargets?: Record<string, boolean>, maxRaiseFanout?: number, dysflowExport?: boolean): ExtractionResult;
|
|
722
|
+
export declare function extractFromSource(filePath: string, source: string, language?: Language, frameworkNames?: string[], vbaTargets?: Record<string, boolean>, maxRaiseFanout?: number, dysflowExport?: boolean, vbaOptions?: VbaExtractionOptions): ExtractionResult;
|
|
714
723
|
//# sourceMappingURL=tree-sitter.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VbaClassifier } from './context';
|
|
2
2
|
import { VbaExtractionRule } from './rules';
|
|
3
3
|
/**
|
|
4
4
|
* Issue #153: the declarative rule table for the calls/SQL concern.
|
|
@@ -7,6 +7,7 @@ import { VbaExtractionRule } from './rules';
|
|
|
7
7
|
* fit the declarative shape. The procedural scanners
|
|
8
8
|
* (`scanRaiseEvents`, `scanCallSites`, `scanMeControlReferences`,
|
|
9
9
|
* `scanSqlInLine`, `scanDoCmdOpenCalls`, `scanDoCmdOpenQuery`,
|
|
10
|
+
* `scanDoCmdObjectCalls`, `scanDoCmdCloseCalls`,
|
|
10
11
|
* `scanFormsBang`, `sweepTempVars`, statement/qualified call
|
|
11
12
|
* detection) walk the masked line scanning for call shapes that
|
|
12
13
|
* don't reduce to a single regex — they stay inside the factory's
|
|
@@ -49,10 +50,4 @@ export declare const RULES: readonly VbaExtractionRule<unknown>[];
|
|
|
49
50
|
* single regex.
|
|
50
51
|
*/
|
|
51
52
|
export declare function createCallsAndSqlClassifier(lines: readonly string[]): VbaClassifier;
|
|
52
|
-
/**
|
|
53
|
-
* Backward-compat wrapper (see procedures.ts). Returns void — the calls
|
|
54
|
-
* sweep never contributed to `hasAnySymbols` directly (every other
|
|
55
|
-
* concern's `count` is the signal the orchestrator reads).
|
|
56
|
-
*/
|
|
57
|
-
export declare function sweepCallsAndSql(ctx: VbaExtractorContext, src: string): void;
|
|
58
53
|
//# sourceMappingURL=call-sweep.d.ts.map
|