@aroman22/codegraph-vba 1.15.0 → 1.16.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.
Files changed (49) hide show
  1. package/dist/bin/daemon-release.d.ts +7 -0
  2. package/dist/db/queries.d.ts +30 -0
  3. package/dist/extraction/access-erd-extractor.d.ts +57 -0
  4. package/dist/extraction/extraction-version.d.ts +1 -1
  5. package/dist/extraction/grammars.d.ts +20 -0
  6. package/dist/extraction/index.d.ts +1 -0
  7. package/dist/extraction/parse-pool.d.ts +8 -3
  8. package/dist/extraction/sql-query-extractor.d.ts +16 -14
  9. package/dist/extraction/sql-table-scan.d.ts +184 -0
  10. package/dist/extraction/tree-sitter.d.ts +10 -1
  11. package/dist/extraction/vba/call-sweep.d.ts +2 -7
  12. package/dist/extraction/vba/calls.d.ts +24 -4
  13. package/dist/extraction/vba/constants.d.ts +7 -14
  14. package/dist/extraction/vba/context.d.ts +443 -7
  15. package/dist/extraction/vba/controls.d.ts +18 -1
  16. package/dist/extraction/vba/declarations.d.ts +1 -6
  17. package/dist/extraction/vba/dims.d.ts +11 -7
  18. package/dist/extraction/vba/docmd.d.ts +29 -2
  19. package/dist/extraction/vba/enums-consts.d.ts +7 -14
  20. package/dist/extraction/vba/error-channel.d.ts +57 -0
  21. package/dist/extraction/vba/errors.d.ts +64 -0
  22. package/dist/extraction/vba/filesystem-statements.d.ts +23 -0
  23. package/dist/extraction/vba/implements.d.ts +1 -6
  24. package/dist/extraction/vba/labels.d.ts +26 -0
  25. package/dist/extraction/vba/module-vars.d.ts +36 -0
  26. package/dist/extraction/vba/options.d.ts +88 -0
  27. package/dist/extraction/vba/parameters.d.ts +35 -0
  28. package/dist/extraction/vba/procedures.d.ts +1 -9
  29. package/dist/extraction/vba/rules.d.ts +10 -5
  30. package/dist/extraction/vba/runtime-objects.d.ts +59 -0
  31. package/dist/extraction/vba/signature.d.ts +57 -0
  32. package/dist/extraction/vba/sql-wrapper.d.ts +76 -3
  33. package/dist/extraction/vba/text-utils.d.ts +62 -2
  34. package/dist/extraction/vba-extractor.d.ts +18 -1
  35. package/dist/extraction/vba-form-extractor.d.ts +28 -14
  36. package/dist/extraction/vba-preprocess.d.ts +89 -3
  37. package/dist/extraction/vba-source.d.ts +0 -10
  38. package/dist/extraction/vba-test-manifest-extractor.d.ts +0 -6
  39. package/dist/mcp/daemon-paths.d.ts +6 -0
  40. package/dist/mcp/daemon-registry.d.ts +82 -7
  41. package/dist/mcp/daemon-watchdog.d.ts +12 -0
  42. package/dist/mcp/daemon.d.ts +20 -1
  43. package/dist/mcp/proxy.d.ts +32 -0
  44. package/dist/project-config.d.ts +43 -2
  45. package/dist/resolution/index.d.ts +47 -2
  46. package/dist/resolution/name-matcher.d.ts +25 -0
  47. package/dist/resolution/vba-runtime-objects.d.ts +11 -11
  48. package/dist/types.d.ts +13 -5
  49. package/package.json +7 -7
@@ -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
@@ -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
@@ -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 = 25;
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
- vbaTargets?: Record<string, boolean>;
51
- /** Issue #152: per-file fanout cap for `RaiseEvent` edges (VBA only). */
52
- maxRaiseFanout?: number;
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 { VbaExtractorContext, VbaClassifier } from './context';
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
@@ -11,13 +11,33 @@ export declare function scanCallSites(ctx: VbaExtractorContext, line: string, fr
11
11
  * scan line, which makes global `:`/`Else` splitting safe.
12
12
  */
13
13
  export declare function splitSingleLineIfClauses(line: string): string[];
14
+ /**
15
+ * Issue #265: the outcome of `detectStatementCall`.
16
+ *
17
+ * `unambiguous` records whether the *syntax* of the statement can only be a
18
+ * procedure call:
19
+ *
20
+ * - `Call MySub` — the `Call` keyword is only valid on a procedure.
21
+ * - `MySub 1, 2` — a constant cannot take an argument list.
22
+ * - `MySub` — AMBIGUOUS: a bare identifier is equally a `Const` read.
23
+ *
24
+ * The call sweep uses this to pick the unresolved-reference kind: `calls` for
25
+ * the two unambiguous shapes, `unqualified-ident` for the bare read (the
26
+ * bucket the const-first disambiguation rule of issue #108 / FR-3.1 needs).
27
+ */
28
+ export interface StatementCall {
29
+ /** The called procedure name (the leading identifier). */
30
+ name: string;
31
+ /** True when the `Call` keyword or an argument list rules out a Const read. */
32
+ unambiguous: boolean;
33
+ }
14
34
  /**
15
35
  * H1: detect a statement-form Sub call (`MySub`, `MySub arg1, x`,
16
- * `Call MySub arg1`). Returns the called proc name, or null for
17
- * declarations, assignments, comments, keyword lines, and the paren form
18
- * (handled by CALL_RE).
36
+ * `Call MySub arg1`). Returns the called proc name plus its syntactic
37
+ * unambiguity (issue #265), or null for declarations, assignments,
38
+ * comments, keyword lines, and the paren form (handled by CALL_RE).
19
39
  */
20
- export declare function detectStatementCall(line: string): string | null;
40
+ export declare function detectStatementCall(line: string): StatementCall | null;
21
41
  /**
22
42
  * H1: emit a same-file `calls` edge for a statement-form Sub call to the
23
43
  * already-emitted function node named `procName`. Returns `true` when a
@@ -10,8 +10,8 @@ export declare const PROC_RE: RegExp;
10
10
  * Promoted from a local regex in `sweepCallsAndSql` so `sweepEnumsAndConsts`
11
11
  * can walk the same proc boundaries and decide Const scope per line.
12
12
  * The `(?:^|:\s*)` prefix tolerates colon-separated single-line procs
13
- * (`Public Sub X(): ... : End Sub`) so the proc stack pops on the same
14
- * physical line.
13
+ * (`Public Sub X(): ... : End Sub`). Classifiers must test procedure start
14
+ * and end independently because both can occur on the same physical line.
15
15
  */
16
16
  export declare const PROCEDURE_END_RE: RegExp;
17
17
  /**
@@ -32,17 +32,10 @@ export declare const CALL_KEYWORD_BLACKLIST: Set<string>;
32
32
  export declare const VBA_KEYWORDS: Set<string>;
33
33
  export declare function isVbaKeyword(name: string): boolean;
34
34
  /**
35
- * Access runtime objects and singletons. Calls on these receivers are
36
- * real VBA calls but the targets are NOT user-defined modules or
37
- * classes they're Access/DAO/ADO runtime types. Synthesizing a
38
- * `function` node for each would pollute the graph with ~20+ junk
39
- * nodes per real-world file (audit W4, June 2026). Skip synthesis
40
- * for any receiver or member in this set.
41
- *
42
- * Note: `DoCmd.RunSQL`, `DoCmd.OpenForm`, etc. still get SQL/edge
43
- * tracking via the dedicated `SQL_WRAPPERS` regex path (REQ-CODE-8),
44
- * which fires BEFORE this scan and uses its own dispatch — so
45
- * blacklisting DoCmd here doesn't lose the SQL-flow edges.
35
+ * Access runtime objects and singletons whose calls the call-site scans drop
36
+ * outright. Issue #245 collapsed this literal into the canonical
37
+ * `RUNTIME_OBJECT_DEFS` in `./runtime-objects.ts`; it is re-exported here so
38
+ * every existing `from './constants'` import keeps working unchanged.
46
39
  */
47
- export declare const RUNTIME_RECEIVER_BLACKLIST: Set<string>;
40
+ export { RUNTIME_RECEIVER_BLACKLIST } from './runtime-objects';
48
41
  //# sourceMappingURL=constants.d.ts.map