@aroman22/codegraph-vba-darwin-arm64 1.10.0 → 1.12.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 (100) hide show
  1. package/lib/dist/bin/codegraph.js +68 -0
  2. package/lib/dist/bin/codegraph.js.map +1 -1
  3. package/lib/dist/cli/stats-vba-rules.d.ts +64 -0
  4. package/lib/dist/cli/stats-vba-rules.d.ts.map +1 -0
  5. package/lib/dist/cli/stats-vba-rules.js +71 -0
  6. package/lib/dist/cli/stats-vba-rules.js.map +1 -0
  7. package/lib/dist/db/queries.d.ts +37 -0
  8. package/lib/dist/db/queries.d.ts.map +1 -1
  9. package/lib/dist/db/queries.js +33 -0
  10. package/lib/dist/db/queries.js.map +1 -1
  11. package/lib/dist/extraction/frameworks/dysflow-export.d.ts +37 -0
  12. package/lib/dist/extraction/frameworks/dysflow-export.d.ts.map +1 -0
  13. package/lib/dist/extraction/frameworks/dysflow-export.js +121 -0
  14. package/lib/dist/extraction/frameworks/dysflow-export.js.map +1 -0
  15. package/lib/dist/extraction/frameworks/index.d.ts +20 -0
  16. package/lib/dist/extraction/frameworks/index.d.ts.map +1 -0
  17. package/lib/dist/extraction/frameworks/index.js +24 -0
  18. package/lib/dist/extraction/frameworks/index.js.map +1 -0
  19. package/lib/dist/extraction/index.d.ts.map +1 -1
  20. package/lib/dist/extraction/index.js +25 -5
  21. package/lib/dist/extraction/index.js.map +1 -1
  22. package/lib/dist/extraction/parse-pool.d.ts +10 -0
  23. package/lib/dist/extraction/parse-pool.d.ts.map +1 -1
  24. package/lib/dist/extraction/parse-pool.js +2 -0
  25. package/lib/dist/extraction/parse-pool.js.map +1 -1
  26. package/lib/dist/extraction/parse-worker.js +6 -2
  27. package/lib/dist/extraction/parse-worker.js.map +1 -1
  28. package/lib/dist/extraction/tree-sitter.d.ts +9 -1
  29. package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
  30. package/lib/dist/extraction/tree-sitter.js +58 -5
  31. package/lib/dist/extraction/tree-sitter.js.map +1 -1
  32. package/lib/dist/extraction/vba/call-sweep.d.ts +43 -0
  33. package/lib/dist/extraction/vba/call-sweep.d.ts.map +1 -1
  34. package/lib/dist/extraction/vba/call-sweep.js +155 -66
  35. package/lib/dist/extraction/vba/call-sweep.js.map +1 -1
  36. package/lib/dist/extraction/vba/calls.d.ts.map +1 -1
  37. package/lib/dist/extraction/vba/calls.js +6 -0
  38. package/lib/dist/extraction/vba/calls.js.map +1 -1
  39. package/lib/dist/extraction/vba/context.d.ts +109 -1
  40. package/lib/dist/extraction/vba/context.d.ts.map +1 -1
  41. package/lib/dist/extraction/vba/context.js +155 -2
  42. package/lib/dist/extraction/vba/context.js.map +1 -1
  43. package/lib/dist/extraction/vba/declarations.d.ts +38 -2
  44. package/lib/dist/extraction/vba/declarations.d.ts.map +1 -1
  45. package/lib/dist/extraction/vba/declarations.js +217 -129
  46. package/lib/dist/extraction/vba/declarations.js.map +1 -1
  47. package/lib/dist/extraction/vba/dims.d.ts +35 -1
  48. package/lib/dist/extraction/vba/dims.d.ts.map +1 -1
  49. package/lib/dist/extraction/vba/dims.js +185 -109
  50. package/lib/dist/extraction/vba/dims.js.map +1 -1
  51. package/lib/dist/extraction/vba/enums-consts.d.ts +47 -7
  52. package/lib/dist/extraction/vba/enums-consts.d.ts.map +1 -1
  53. package/lib/dist/extraction/vba/enums-consts.js +215 -139
  54. package/lib/dist/extraction/vba/enums-consts.js.map +1 -1
  55. package/lib/dist/extraction/vba/event-synth.d.ts +3 -0
  56. package/lib/dist/extraction/vba/event-synth.d.ts.map +1 -0
  57. package/lib/dist/extraction/vba/event-synth.js +176 -0
  58. package/lib/dist/extraction/vba/event-synth.js.map +1 -0
  59. package/lib/dist/extraction/vba/implements.d.ts +16 -0
  60. package/lib/dist/extraction/vba/implements.d.ts.map +1 -1
  61. package/lib/dist/extraction/vba/implements.js +43 -12
  62. package/lib/dist/extraction/vba/implements.js.map +1 -1
  63. package/lib/dist/extraction/vba/procedures.d.ts +20 -0
  64. package/lib/dist/extraction/vba/procedures.d.ts.map +1 -1
  65. package/lib/dist/extraction/vba/procedures.js +48 -13
  66. package/lib/dist/extraction/vba/procedures.js.map +1 -1
  67. package/lib/dist/extraction/vba/rules.d.ts +129 -0
  68. package/lib/dist/extraction/vba/rules.d.ts.map +1 -0
  69. package/lib/dist/extraction/vba/rules.js +63 -0
  70. package/lib/dist/extraction/vba/rules.js.map +1 -0
  71. package/lib/dist/extraction/vba/text-utils.d.ts +1 -0
  72. package/lib/dist/extraction/vba/text-utils.d.ts.map +1 -1
  73. package/lib/dist/extraction/vba/text-utils.js +4 -2
  74. package/lib/dist/extraction/vba/text-utils.js.map +1 -1
  75. package/lib/dist/extraction/vba-extractor.d.ts +77 -1
  76. package/lib/dist/extraction/vba-extractor.d.ts.map +1 -1
  77. package/lib/dist/extraction/vba-extractor.js +182 -15
  78. package/lib/dist/extraction/vba-extractor.js.map +1 -1
  79. package/lib/dist/extraction/vba-preprocess.d.ts +11 -1
  80. package/lib/dist/extraction/vba-preprocess.d.ts.map +1 -1
  81. package/lib/dist/extraction/vba-preprocess.js +45 -16
  82. package/lib/dist/extraction/vba-preprocess.js.map +1 -1
  83. package/lib/dist/extraction/vba-timing.d.ts +38 -0
  84. package/lib/dist/extraction/vba-timing.d.ts.map +1 -0
  85. package/lib/dist/extraction/vba-timing.js +203 -0
  86. package/lib/dist/extraction/vba-timing.js.map +1 -0
  87. package/lib/dist/index.d.ts.map +1 -1
  88. package/lib/dist/index.js +22 -0
  89. package/lib/dist/index.js.map +1 -1
  90. package/lib/dist/project-config.d.ts +31 -0
  91. package/lib/dist/project-config.d.ts.map +1 -1
  92. package/lib/dist/project-config.js +75 -22
  93. package/lib/dist/project-config.js.map +1 -1
  94. package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
  95. package/lib/dist/resolution/frameworks/index.js +7 -0
  96. package/lib/dist/resolution/frameworks/index.js.map +1 -1
  97. package/lib/node_modules/.modules.yaml +1 -1
  98. package/lib/node_modules/.pnpm-workspace-state-v1.json +1 -1
  99. package/lib/package.json +2 -1
  100. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RULES = void 0;
3
4
  exports.createEnumsConstsClassifier = createEnumsConstsClassifier;
4
5
  exports.sweepEnumsAndConsts = sweepEnumsAndConsts;
5
6
  /**
@@ -11,6 +12,7 @@ exports.sweepEnumsAndConsts = sweepEnumsAndConsts;
11
12
  const tree_sitter_helpers_1 = require("../tree-sitter-helpers");
12
13
  const constants_1 = require("./constants");
13
14
  const text_utils_1 = require("./text-utils");
15
+ const rules_1 = require("./rules");
14
16
  /** `[visibility] Enum <Name>` — opens an enum block. */
15
17
  const ENUM_START_RE = /^\s*(?:(Public|Private|Friend|Global)\s+)?Enum\s+(\p{L}[\p{L}\p{N}_]*)/iu;
16
18
  /** `End Enum` — closes the current enum block. */
@@ -25,87 +27,170 @@ const ENUM_MEMBER_RE = /^\s*(\p{L}[\p{L}\p{N}_]*)\s*(?:=|$)/u;
25
27
  /** `[visibility] Const <decls>` — captures visibility (1) and the rest (2). */
26
28
  const CONST_DECL_RE = /^\s*(?:(Public|Private|Friend|Global)\s+)?Const\s+(.+)$/i;
27
29
  /**
28
- * Issue #83: factory for the enum / const classifier. Closure state:
29
- * `currentEnum` (open `Enum ... End Enum` block).
30
+ * Issue #153: the declarative rule table for the enum / const concern.
31
+ * Six rules, partitioned by where they fire:
30
32
  *
31
- * Also resets + advances the SHARED `ctx.procStack`/`ctx.currentProcKey`
32
- * per line same protocol the pre-#83 sweep followed. The calls-sql
33
- * classifier runs AFTER this one in the per-line dispatch order and
34
- * applies the same protocol, so the end-of-line scope state is identical
35
- * to the legacy sequential-sweep behaviour.
33
+ * - `proc-start` (outside-enum-block) match a `Sub` /
34
+ * `Function` / `Property` header; push onto
35
+ * `ctx.procStack` and set `ctx.currentProcKey`
36
+ * so subsequent Const writes land in the
37
+ * per-proc resolution bucket.
38
+ * - `proc-end` (outside-enum-block) — match `End Sub` /
39
+ * `End Function` / `End Property`; pop the
40
+ * matching `procStack` entry.
41
+ * - `enum-start` (outside-enum-block) — match `[visibility]
42
+ * Enum <Name>`; emit an `enum` node + `contains`
43
+ * edge and mark `ctx.vbaEnumBlock`.
44
+ * - `enum-end` (inside-enum-block) — match `End Enum`; clear
45
+ * `ctx.vbaEnumBlock`.
46
+ * - `enum-member` (inside-enum-block) — match `<MemberName>
47
+ * [= <value>]`; emit an `enum_member` node + a
48
+ * `contains` edge from the open enum.
49
+ * - `const-decl` (outside-enum-block) — match `[visibility]
50
+ * Const <decls>`; always write the per-scope
51
+ * resolution bucket, and emit a `constant` node
52
+ * + `contains` edge ONLY when not inside a proc
53
+ * (proc-local Consts are not module symbols).
54
+ *
55
+ * The inter-line `ctx.procStack` / `ctx.currentProcKey` state is
56
+ * SHARED with the calls/SQL classifier (issue #52 protocol). The
57
+ * `ctx.vbaEnumBlock` state is local to this concern and lives on
58
+ * `ctx` for the same RULES-table-friendliness reason as
59
+ * `vbaDeclTypeBlock`.
36
60
  */
37
- function createEnumsConstsClassifier() {
38
- let currentEnum = null;
39
- const cls = {
40
- name: 'enumsConsts',
41
- count: 0,
42
- classifyLine(line, i, ctx) {
43
- const lineNum = i + 1;
44
- // Issue #52: track proc scope so Const declarations on this line
45
- // can decide whether they belong to the module (currentProcKey
46
- // === 'module') or to the top-most procedure (write the per-proc
47
- // bucket, skip the module-level `constant` node emission).
48
- //
49
- // PROC_RE cannot overlap with CONST_DECL_RE on the same physical
50
- // line (different leading keywords), so it is safe to advance the
51
- // stack here and then fall through to the rest of the body.
52
- const procStart = constants_1.PROC_RE.exec(line);
53
- if (procStart) {
54
- ctx.procStack.push(lineNum);
55
- ctx.currentProcKey = String(lineNum);
56
- }
57
- else if (constants_1.PROCEDURE_END_RE.test(line) && ctx.procStack.length > 0) {
61
+ exports.RULES = [
62
+ (0, rules_1.defineRule)({
63
+ id: 'proc-start',
64
+ description: 'Match a `Sub` / `Function` / `Property` header; push `lineNum` onto `ctx.procStack` and set `ctx.currentProcKey` so subsequent Const writes land in the per-proc resolution bucket.',
65
+ pattern: constants_1.PROC_RE,
66
+ requires: 'outside-enum-block',
67
+ emit: (_m, ctx, _line, lineNum) => {
68
+ ctx.procStack.push(lineNum);
69
+ ctx.currentProcKey = String(lineNum);
70
+ return { startLine: lineNum };
71
+ },
72
+ }),
73
+ (0, rules_1.defineRule)({
74
+ id: 'proc-end',
75
+ description: 'Match an `End Sub` / `End Function` / `End Property`; pop the matching `procStack` entry and rewind `ctx.currentProcKey` to the new top (or `module`).',
76
+ pattern: constants_1.PROCEDURE_END_RE,
77
+ requires: 'outside-enum-block',
78
+ emit: (_m, ctx) => {
79
+ if (ctx.procStack.length > 0)
58
80
  ctx.procStack.pop();
59
- ctx.currentProcKey =
60
- ctx.procStack.length > 0
61
- ? String(ctx.procStack[ctx.procStack.length - 1])
62
- : 'module';
63
- }
64
- if (currentEnum) {
65
- if (ENUM_END_RE.test(line)) {
66
- currentEnum = null;
67
- return;
68
- }
69
- const mm = ENUM_MEMBER_RE.exec(line);
70
- if (mm) {
71
- const memberName = mm[1] ?? '';
72
- if (memberName) {
73
- const memberId = (0, tree_sitter_helpers_1.generateNodeId)(ctx.filePath, 'enum_member', memberName, lineNum);
74
- ctx.nodes.push({
75
- id: memberId,
76
- kind: 'enum_member',
77
- name: memberName,
78
- qualifiedName: `${currentEnum.name}.${memberName}`,
79
- filePath: ctx.filePath,
80
- language: 'vba',
81
- startLine: lineNum,
82
- endLine: lineNum,
83
- startColumn: 0,
84
- endColumn: line.length,
85
- updatedAt: Date.now(),
86
- });
87
- // enum → member: source is known, emit directly (not pending).
88
- ctx.edges.push({
89
- source: currentEnum.id,
90
- target: memberId,
91
- kind: 'contains',
92
- });
93
- }
81
+ ctx.currentProcKey =
82
+ ctx.procStack.length > 0
83
+ ? String(ctx.procStack[ctx.procStack.length - 1])
84
+ : 'module';
85
+ return { kind: 'proc-end' };
86
+ },
87
+ }),
88
+ (0, rules_1.defineRule)({
89
+ id: 'enum-start',
90
+ description: 'Match a `[Public|Private|Friend|Global] Enum <Name>` block header; emit an `enum` node + `contains` edge and mark `ctx.vbaEnumBlock` so subsequent member lines route to `enum-member` / `End Enum` lines route to `enum-end`.',
91
+ pattern: ENUM_START_RE,
92
+ requires: 'outside-enum-block',
93
+ emit: (m, ctx, line, lineNum) => {
94
+ const visibility = (0, text_utils_1.foldVisibility)(m[1] ?? '');
95
+ const name = m[2] ?? '';
96
+ if (!name)
97
+ return null;
98
+ const enumId = (0, tree_sitter_helpers_1.generateNodeId)(ctx.filePath, 'enum', name, lineNum);
99
+ ctx.nodes.push({
100
+ id: enumId,
101
+ kind: 'enum',
102
+ name,
103
+ qualifiedName: name,
104
+ filePath: ctx.filePath,
105
+ language: 'vba',
106
+ startLine: lineNum,
107
+ endLine: lineNum,
108
+ startColumn: 0,
109
+ endColumn: line.length,
110
+ visibility,
111
+ updatedAt: Date.now(),
112
+ });
113
+ ctx.pushContainsFromModule(enumId);
114
+ ctx.vbaEnumBlock = { id: enumId, name };
115
+ return { name, enumId };
116
+ },
117
+ }),
118
+ (0, rules_1.defineRule)({
119
+ id: 'enum-end',
120
+ description: 'Match `End Enum` while inside an enum block; emit nothing and clear `ctx.vbaEnumBlock` so subsequent lines route back to the outside-enum-block rules.',
121
+ pattern: ENUM_END_RE,
122
+ requires: 'inside-enum-block',
123
+ emit: (_m, ctx) => {
124
+ ctx.vbaEnumBlock = null;
125
+ return { kind: 'end-enum-block' };
126
+ },
127
+ }),
128
+ (0, rules_1.defineRule)({
129
+ id: 'enum-member',
130
+ description: 'Match `<MemberName> [= <value>]` inside an open enum block; emit an `enum_member` node + a `contains` edge from the open enum.',
131
+ pattern: ENUM_MEMBER_RE,
132
+ requires: 'inside-enum-block',
133
+ emit: (m, ctx, line, lineNum) => {
134
+ const memberName = m[1] ?? '';
135
+ if (!memberName || !ctx.vbaEnumBlock)
136
+ return null;
137
+ const memberId = (0, tree_sitter_helpers_1.generateNodeId)(ctx.filePath, 'enum_member', memberName, lineNum);
138
+ ctx.nodes.push({
139
+ id: memberId,
140
+ kind: 'enum_member',
141
+ name: memberName,
142
+ qualifiedName: `${ctx.vbaEnumBlock.name}.${memberName}`,
143
+ filePath: ctx.filePath,
144
+ language: 'vba',
145
+ startLine: lineNum,
146
+ endLine: lineNum,
147
+ startColumn: 0,
148
+ endColumn: line.length,
149
+ updatedAt: Date.now(),
150
+ });
151
+ // enum → member: source is known, emit directly (not pending).
152
+ ctx.edges.push({
153
+ source: ctx.vbaEnumBlock.id,
154
+ target: memberId,
155
+ kind: 'contains',
156
+ });
157
+ return { name: memberName };
158
+ },
159
+ }),
160
+ (0, rules_1.defineRule)({
161
+ id: 'const-decl',
162
+ description: 'Match a `[Public|Private|Friend|Global] Const <decls>` declaration; always write the per-scope resolution bucket (issue #52) and additionally emit a `constant` node + `contains` edge ONLY when not inside a proc (proc-local Consts are not module symbols).',
163
+ pattern: CONST_DECL_RE,
164
+ requires: 'outside-enum-block',
165
+ emit: (m, ctx, line, lineNum) => {
166
+ const visibility = (0, text_utils_1.foldVisibility)(m[1] ?? '');
167
+ const body = m[2] ?? '';
168
+ const declarations = (0, text_utils_1.parseConstDeclarations)(body);
169
+ let count = 0;
170
+ for (const declaration of declarations) {
171
+ const constName = declaration.name;
172
+ if (!constName)
173
+ continue;
174
+ // Issue #52: every Const line (module-level or proc-local)
175
+ // writes into a per-scope resolution bucket so
176
+ // `DoCmd.OpenForm FORM_X` later resolves correctly; module-level
177
+ // Consts additionally emit a `constant` graph node + the
178
+ // module→constant `contains` edge. Proc-local Consts skip both
179
+ // (the const is not a module symbol, so the wrong-containment
180
+ // node + edge the pre-fix code emitted are gone), but the
181
+ // per-proc bucket keeps OpenForm/OpenQuery argument
182
+ // resolution working exactly as before.
183
+ if (declaration.value !== null) {
184
+ ctx.setLocalConstInScope(ctx.currentProcKey, constName, declaration.value);
94
185
  }
95
- return;
96
- }
97
- const enumStart = ENUM_START_RE.exec(line);
98
- if (enumStart) {
99
- const visibility = (0, text_utils_1.foldVisibility)(enumStart[1] ?? '');
100
- const name = enumStart[2] ?? '';
101
- if (!name)
102
- return;
103
- const enumId = (0, tree_sitter_helpers_1.generateNodeId)(ctx.filePath, 'enum', name, lineNum);
186
+ if (ctx.procStack.length > 0)
187
+ continue;
188
+ const constId = (0, tree_sitter_helpers_1.generateNodeId)(ctx.filePath, 'constant', constName, lineNum);
104
189
  ctx.nodes.push({
105
- id: enumId,
106
- kind: 'enum',
107
- name,
108
- qualifiedName: name,
190
+ id: constId,
191
+ kind: 'constant',
192
+ name: constName,
193
+ qualifiedName: constName,
109
194
  filePath: ctx.filePath,
110
195
  language: 'vba',
111
196
  startLine: lineNum,
@@ -113,76 +198,67 @@ function createEnumsConstsClassifier() {
113
198
  startColumn: 0,
114
199
  endColumn: line.length,
115
200
  visibility,
201
+ metadata: {
202
+ asType: declaration.asType,
203
+ ...(declaration.value !== null ? { value: declaration.value } : {}),
204
+ },
116
205
  updatedAt: Date.now(),
117
206
  });
118
- ctx.pushContainsFromModule(enumId);
119
- currentEnum = { id: enumId, name };
120
- this.count++;
121
- return;
207
+ ctx.pushContainsFromModule(constId);
208
+ count++;
122
209
  }
123
- const constDecl = CONST_DECL_RE.exec(line);
124
- if (constDecl) {
125
- const visibility = (0, text_utils_1.foldVisibility)(constDecl[1] ?? '');
126
- const body = constDecl[2] ?? '';
127
- const declarations = (0, text_utils_1.parseConstDeclarations)(body);
128
- for (const declaration of declarations) {
129
- const constName = declaration.name;
130
- if (!constName)
131
- continue;
132
- // Issue #52: every Const line (module-level or proc-local)
133
- // writes into a per-scope resolution bucket so
134
- // `DoCmd.OpenForm FORM_X` later resolves correctly; module-level
135
- // Consts additionally emit a `constant` graph node + the
136
- // module→constant `contains` edge. Proc-local Consts skip both
137
- // (the const is not a module symbol, so the wrong-containment
138
- // node + edge the pre-fix code emitted are gone), but the
139
- // per-proc bucket keeps OpenForm/OpenQuery argument
140
- // resolution working exactly as before.
141
- if (declaration.value !== null) {
142
- ctx.setLocalConstInScope(ctx.currentProcKey, constName, declaration.value);
143
- }
144
- if (ctx.procStack.length > 0)
145
- continue;
146
- const constId = (0, tree_sitter_helpers_1.generateNodeId)(ctx.filePath, 'constant', constName, lineNum);
147
- ctx.nodes.push({
148
- id: constId,
149
- kind: 'constant',
150
- name: constName,
151
- qualifiedName: constName,
152
- filePath: ctx.filePath,
153
- language: 'vba',
154
- startLine: lineNum,
155
- endLine: lineNum,
156
- startColumn: 0,
157
- endColumn: line.length,
158
- visibility,
159
- metadata: declaration.value !== null ? { value: declaration.value } : undefined,
160
- updatedAt: Date.now(),
161
- });
162
- ctx.pushContainsFromModule(constId);
163
- this.count++;
210
+ return { count };
211
+ },
212
+ }),
213
+ ];
214
+ /**
215
+ * Issue #83: factory for the enum / const classifier.
216
+ *
217
+ * The body walks the declarative `RULES` table (Issue #153) and
218
+ * honours each rule's `requires` precondition. The inter-line
219
+ * state `ctx.procStack`, `ctx.currentProcKey`, and
220
+ * `ctx.vbaEnumBlock` lives on `ctx` so the RULES table's `emit`
221
+ * functions can read/write it without taking a closure reference.
222
+ *
223
+ * Issue #52: the first invocation also resets the shared proc-stack
224
+ * + lookup key so leftover state from a previous `extract()` (only
225
+ * possible in tests that construct a fresh extractor and run twice)
226
+ * never leaks across sweeps. The walk below updates both every
227
+ * iteration; `sweepCallsAndSql` resets again at its own start, so
228
+ * the protocol stays consistent across both classifiers.
229
+ */
230
+ function createEnumsConstsClassifier() {
231
+ let initialized = false;
232
+ const cls = {
233
+ name: 'enumsConsts',
234
+ count: 0,
235
+ classifyLine(line, i, ctx) {
236
+ if (!initialized) {
237
+ ctx.procStack.length = 0;
238
+ ctx.currentProcKey = 'module';
239
+ initialized = true;
240
+ }
241
+ const lineNum = i + 1;
242
+ for (const rule of exports.RULES) {
243
+ if (rule.requires === 'inside-enum-block' && !ctx.vbaEnumBlock)
244
+ continue;
245
+ if (rule.requires === 'outside-enum-block' && ctx.vbaEnumBlock)
246
+ continue;
247
+ const m = (0, rules_1.matchRule)(rule.pattern, line);
248
+ if (!m)
249
+ continue;
250
+ const result = rule.emit(m, ctx, line, lineNum);
251
+ if (result !== null && result !== undefined) {
252
+ this.count += rule.count ? rule.count(result) : 1;
164
253
  }
254
+ // `enum-end` cleared the enum block — nothing else on this
255
+ // line can apply. The legacy cascade did the same short-circuit
256
+ // via `return`.
257
+ if (rule.id === 'enum-end')
258
+ break;
165
259
  }
166
260
  },
167
261
  };
168
- // Issue #52: reset the shared scope stack + lookup key so leftover
169
- // state from a previous extract() (impossible in production but
170
- // possible in unit tests that construct a fresh extractor and run
171
- // twice) never leaks across sweeps. The walk below updates both
172
- // every iteration; `sweepCallsAndSql` resets again at its own
173
- // start, before any OpenForm/OpenQuery reader consults them.
174
- // We re-bind the classifier to call this reset at the start of
175
- // its first invocation.
176
- const originalClassify = cls.classifyLine;
177
- let initialized = false;
178
- cls.classifyLine = function (line, i, ctx) {
179
- if (!initialized) {
180
- ctx.procStack.length = 0;
181
- ctx.currentProcKey = 'module';
182
- initialized = true;
183
- }
184
- return originalClassify.call(this, line, i, ctx);
185
- };
186
262
  return cls;
187
263
  }
188
264
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"enums-consts.js","sourceRoot":"","sources":["../../../src/extraction/vba/enums-consts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"enums-consts.js","sourceRoot":"","sources":["../../../src/extraction/vba/enums-consts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { QueryBuilder } from '../../db/queries';
2
+ export declare function synthesizeVbaEventHandlerEdges(queries: QueryBuilder): number;
3
+ //# sourceMappingURL=event-synth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-synth.d.ts","sourceRoot":"","sources":["../../../src/extraction/vba/event-synth.ts"],"names":[],"mappings":"AA+DA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAahD,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAmF5E"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.synthesizeVbaEventHandlerEdges = synthesizeVbaEventHandlerEdges;
4
+ function synthesizeVbaEventHandlerEdges(queries) {
5
+ // --- Phase 1: collect pairs ---------------------------------------------
6
+ // Walk every `vba-withevents` `references` edge. The SOURCE is the
7
+ // subscriber's module/class node (its `filePath` scopes the handler
8
+ // Sub lookup); the TARGET is the REAL event-declaring class node
9
+ // (after `resolveVbaReferenceStubs` repointed it from the synthetic
10
+ // class stub). The metadata carries the WithEvents variable name
11
+ // (`m_X`) — issue #150 change to `VbaExtractorContext.emitReference`.
12
+ const bindings = queryWithEventsBindings(queries);
13
+ if (bindings.length === 0)
14
+ return 0;
15
+ // key = eventNodeId (string), value = the pair. We keep the FIRST
16
+ // binding per event node — multiple `WithEvents` vars on the same
17
+ // class binding to the same event from the same file is rare; if it
18
+ // ever happens the second binding's variable name is silently
19
+ // shadowed by the first, which is fine because we only emit one
20
+ // `event-handler` edge per raiser anyway.
21
+ const pairsByEventId = new Map();
22
+ for (const binding of bindings) {
23
+ if (!binding.variableName)
24
+ continue;
25
+ // Find every event node in the real event-declaring class's file.
26
+ // iterateNodesByKind streams the events without materializing the
27
+ // whole table (cheap on a few hundred-event project, O(1) memory
28
+ // for million-event projects).
29
+ for (const eventNode of queries.iterateNodesByKind('event')) {
30
+ if (eventNode.language !== 'vba')
31
+ continue;
32
+ if (eventNode.filePath !== binding.eventClassFilePath)
33
+ continue;
34
+ // Handler Sub name follows the WithEvents naming convention:
35
+ // `m_<variableName>_<eventName>` (e.g. `m_Notifier_DataChanged`).
36
+ const handlerName = `${binding.variableName}_${eventNode.name}`;
37
+ const handlerSub = findHandlerSubInFile(queries, binding.subscriberFilePath, handlerName);
38
+ if (!handlerSub)
39
+ continue;
40
+ if (pairsByEventId.has(eventNode.id))
41
+ continue;
42
+ pairsByEventId.set(eventNode.id, {
43
+ handlerNode: handlerSub,
44
+ variableName: binding.variableName,
45
+ });
46
+ }
47
+ }
48
+ if (pairsByEventId.size === 0)
49
+ return 0;
50
+ // --- Phase 2: connect at RaiseEvent sites --------------------------------
51
+ const raiseRows = queries.getRaisesEventEdges();
52
+ const seenTuples = new Set();
53
+ const newEdges = [];
54
+ for (const re of raiseRows) {
55
+ const pair = pairsByEventId.get(re.target);
56
+ if (!pair)
57
+ continue;
58
+ const tupleKey = `${re.source}\0${pair.handlerNode.id}`;
59
+ if (seenTuples.has(tupleKey))
60
+ continue;
61
+ if (queries.edgeExists(re.source, pair.handlerNode.id, 'event-handler')) {
62
+ seenTuples.add(tupleKey);
63
+ continue;
64
+ }
65
+ seenTuples.add(tupleKey);
66
+ const meta = parseMetadata(re.metadata);
67
+ const eventName = typeof meta?.eventName === 'string' ? meta.eventName : '';
68
+ newEdges.push({
69
+ source: re.source,
70
+ target: pair.handlerNode.id,
71
+ kind: 'event-handler',
72
+ provenance: 'heuristic',
73
+ metadata: {
74
+ synthesizedBy: 'vba-event-handler',
75
+ eventName,
76
+ variableName: pair.variableName,
77
+ },
78
+ line: re.line ?? undefined,
79
+ column: re.col ?? undefined,
80
+ });
81
+ }
82
+ if (newEdges.length > 0) {
83
+ queries.insertEdges(newEdges);
84
+ }
85
+ return newEdges.length;
86
+ }
87
+ /**
88
+ * Discover every WithEvents binding in the project by walking the
89
+ * `vba-withevents` `references` edges. Each binding carries:
90
+ * - `subscriberFilePath` → where the handler Sub must live
91
+ * - `eventClassFilePath` → where the event node lives
92
+ * - `variableName` → the `m_X` part of `m_X_<EventName>`
93
+ *
94
+ * Uses one SQL query (the new `getReferencesBySynthesizedBy` helper)
95
+ * + per-edge `getNodeById` lookups so the cost is O(bindings)
96
+ * regardless of total node count. Cache-friendly: the QueryBuilder's
97
+ * LRU node cache absorbs repeated `getNodeById` calls.
98
+ */
99
+ function queryWithEventsBindings(queries) {
100
+ const rows = queries.getReferencesBySynthesizedBy('vba-withevents');
101
+ const out = [];
102
+ for (const row of rows) {
103
+ const meta = parseMetadata(row.metadata);
104
+ if (meta?.synthesizedBy !== 'vba-withevents')
105
+ continue;
106
+ const variableName = typeof meta?.variableName === 'string' ? meta.variableName : '';
107
+ if (!variableName)
108
+ continue;
109
+ // Subscriber file: the source is the subscriber's class node.
110
+ const subscriberNode = queries.getNodeById(row.source);
111
+ if (!subscriberNode || !subscriberNode.filePath)
112
+ continue;
113
+ // Event-declaring class file: the target is the real class node
114
+ // (after `resolveVbaReferenceStubs` repointed it from the synthetic
115
+ // class stub). We accept `class` / `module` / `interface` / `enum`
116
+ // / `struct` / `type_alias` — whatever kind the resolver landed on.
117
+ const eventClassNode = queries.getNodeById(row.target);
118
+ if (!eventClassNode || !eventClassNode.filePath)
119
+ continue;
120
+ if (eventClassNode.language !== 'vba')
121
+ continue;
122
+ if (eventClassNode.filePath === subscriberNode.filePath)
123
+ continue;
124
+ out.push({
125
+ subscriberFilePath: subscriberNode.filePath,
126
+ eventClassFilePath: eventClassNode.filePath,
127
+ variableName,
128
+ });
129
+ }
130
+ return out;
131
+ }
132
+ /**
133
+ * Find a function (Sub) node in `filePath` whose name matches
134
+ * `handlerName` (case-insensitive, since VBA identifiers are case-
135
+ * insensitive). Uses a narrow SQL query (the QueryBuilder doesn't
136
+ * expose a public name+file+kind lookup, so we go through
137
+ * `getNodesByFile` and filter — filePath-keyed lookups are fast on
138
+ * the `idx_nodes_file_path` index).
139
+ */
140
+ function findHandlerSubInFile(queries, filePath, handlerName) {
141
+ const lower = handlerName.toLowerCase();
142
+ // getNodesByFile returns nodes ordered by start_line; the order
143
+ // doesn't matter for the existence check, only the (name, filePath,
144
+ // kind='function') match.
145
+ const candidates = queries.getNodesByFile(filePath);
146
+ for (const node of candidates) {
147
+ if (node.kind !== 'function')
148
+ continue;
149
+ if (node.language !== 'vba')
150
+ continue;
151
+ if (node.name.toLowerCase() !== lower)
152
+ continue;
153
+ return node;
154
+ }
155
+ return null;
156
+ }
157
+ /**
158
+ * Safe-parse the metadata JSON column. The schema stores it as TEXT;
159
+ * an absent or malformed cell returns `null` (treated as "no metadata"
160
+ * by callers). Mirrors the same shape used elsewhere in the codebase.
161
+ */
162
+ function parseMetadata(raw) {
163
+ if (!raw)
164
+ return null;
165
+ try {
166
+ const parsed = JSON.parse(raw);
167
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
168
+ return parsed;
169
+ }
170
+ }
171
+ catch {
172
+ /* fall through */
173
+ }
174
+ return null;
175
+ }
176
+ //# sourceMappingURL=event-synth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-synth.js","sourceRoot":"","sources":["../../../src/extraction/vba/event-synth.ts"],"names":[],"mappings":"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"}