@aroman22/codegraph-vba-darwin-arm64 1.5.2 → 1.6.1
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/bin/codegraph +5 -0
- package/lib/dist/bin/codegraph.d.ts +1 -1
- package/lib/dist/bin/codegraph.d.ts.map +1 -1
- package/lib/dist/bin/codegraph.js +307 -81
- package/lib/dist/bin/codegraph.js.map +1 -1
- package/lib/dist/bin/command-supervision.d.ts +38 -1
- package/lib/dist/bin/command-supervision.d.ts.map +1 -1
- package/lib/dist/bin/command-supervision.js +22 -3
- package/lib/dist/bin/command-supervision.js.map +1 -1
- package/lib/dist/db/index.d.ts +84 -5
- package/lib/dist/db/index.d.ts.map +1 -1
- package/lib/dist/db/index.js +209 -12
- package/lib/dist/db/index.js.map +1 -1
- package/lib/dist/db/migrations.d.ts +1 -1
- package/lib/dist/db/migrations.d.ts.map +1 -1
- package/lib/dist/db/migrations.js +80 -3
- package/lib/dist/db/migrations.js.map +1 -1
- package/lib/dist/db/queries.d.ts +116 -4
- package/lib/dist/db/queries.d.ts.map +1 -1
- package/lib/dist/db/queries.js +294 -7
- package/lib/dist/db/queries.js.map +1 -1
- package/lib/dist/db/schema.sql +43 -1
- package/lib/dist/db/wal-valve.d.ts +106 -0
- package/lib/dist/db/wal-valve.d.ts.map +1 -0
- package/lib/dist/db/wal-valve.js +208 -0
- package/lib/dist/db/wal-valve.js.map +1 -0
- package/lib/dist/directory.d.ts +9 -5
- package/lib/dist/directory.d.ts.map +1 -1
- package/lib/dist/directory.js +210 -19
- package/lib/dist/directory.js.map +1 -1
- package/lib/dist/extraction/cfml-extractor.d.ts +107 -0
- package/lib/dist/extraction/cfml-extractor.d.ts.map +1 -0
- package/lib/dist/extraction/cfml-extractor.js +494 -0
- package/lib/dist/extraction/cfml-extractor.js.map +1 -0
- package/lib/dist/extraction/grammars.d.ts +25 -1
- package/lib/dist/extraction/grammars.d.ts.map +1 -1
- package/lib/dist/extraction/grammars.js +177 -23
- package/lib/dist/extraction/grammars.js.map +1 -1
- package/lib/dist/extraction/index.d.ts +47 -2
- package/lib/dist/extraction/index.d.ts.map +1 -1
- package/lib/dist/extraction/index.js +568 -51
- package/lib/dist/extraction/index.js.map +1 -1
- package/lib/dist/extraction/languages/arkts.d.ts +3 -0
- package/lib/dist/extraction/languages/arkts.d.ts.map +1 -0
- package/lib/dist/extraction/languages/arkts.js +127 -0
- package/lib/dist/extraction/languages/arkts.js.map +1 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts +98 -0
- package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/lib/dist/extraction/languages/c-cpp.js +563 -1
- package/lib/dist/extraction/languages/c-cpp.js.map +1 -1
- package/lib/dist/extraction/languages/cfquery.d.ts +12 -0
- package/lib/dist/extraction/languages/cfquery.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfquery.js +28 -0
- package/lib/dist/extraction/languages/cfquery.js.map +1 -0
- package/lib/dist/extraction/languages/cfscript.d.ts +3 -0
- package/lib/dist/extraction/languages/cfscript.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cfscript.js +73 -0
- package/lib/dist/extraction/languages/cfscript.js.map +1 -0
- package/lib/dist/extraction/languages/cobol.d.ts +33 -0
- package/lib/dist/extraction/languages/cobol.d.ts.map +1 -0
- package/lib/dist/extraction/languages/cobol.js +499 -0
- package/lib/dist/extraction/languages/cobol.js.map +1 -0
- package/lib/dist/extraction/languages/erlang.d.ts +3 -0
- package/lib/dist/extraction/languages/erlang.d.ts.map +1 -0
- package/lib/dist/extraction/languages/erlang.js +350 -0
- package/lib/dist/extraction/languages/erlang.js.map +1 -0
- package/lib/dist/extraction/languages/index.d.ts.map +1 -1
- package/lib/dist/extraction/languages/index.js +18 -0
- package/lib/dist/extraction/languages/index.js.map +1 -1
- package/lib/dist/extraction/languages/nix.d.ts +3 -0
- package/lib/dist/extraction/languages/nix.d.ts.map +1 -0
- package/lib/dist/extraction/languages/nix.js +294 -0
- package/lib/dist/extraction/languages/nix.js.map +1 -0
- package/lib/dist/extraction/languages/solidity.d.ts +3 -0
- package/lib/dist/extraction/languages/solidity.d.ts.map +1 -0
- package/lib/dist/extraction/languages/solidity.js +293 -0
- package/lib/dist/extraction/languages/solidity.js.map +1 -0
- package/lib/dist/extraction/languages/terraform.d.ts +3 -0
- package/lib/dist/extraction/languages/terraform.d.ts.map +1 -0
- package/lib/dist/extraction/languages/terraform.js +641 -0
- package/lib/dist/extraction/languages/terraform.js.map +1 -0
- package/lib/dist/extraction/languages/vbnet.d.ts +11 -0
- package/lib/dist/extraction/languages/vbnet.d.ts.map +1 -0
- package/lib/dist/extraction/languages/vbnet.js +141 -0
- package/lib/dist/extraction/languages/vbnet.js.map +1 -0
- package/lib/dist/extraction/mybatis-extractor.d.ts +30 -10
- package/lib/dist/extraction/mybatis-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/mybatis-extractor.js +140 -38
- package/lib/dist/extraction/mybatis-extractor.js.map +1 -1
- package/lib/dist/extraction/parse-pool.d.ts +28 -1
- package/lib/dist/extraction/parse-pool.d.ts.map +1 -1
- package/lib/dist/extraction/parse-pool.js +76 -7
- package/lib/dist/extraction/parse-pool.js.map +1 -1
- package/lib/dist/extraction/parse-worker.js +11 -4
- package/lib/dist/extraction/parse-worker.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter-helpers.js +1 -0
- package/lib/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts +20 -1
- package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.d.ts +60 -1
- package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/lib/dist/extraction/tree-sitter.js +905 -20
- package/lib/dist/extraction/tree-sitter.js.map +1 -1
- package/lib/dist/extraction/vba/call-sweep.d.ts +3 -0
- package/lib/dist/extraction/vba/call-sweep.d.ts.map +1 -0
- package/lib/dist/extraction/vba/call-sweep.js +206 -0
- package/lib/dist/extraction/vba/call-sweep.js.map +1 -0
- package/lib/dist/extraction/vba/calls.d.ts +55 -0
- package/lib/dist/extraction/vba/calls.d.ts.map +1 -0
- package/lib/dist/extraction/vba/calls.js +439 -0
- package/lib/dist/extraction/vba/calls.js.map +1 -0
- package/lib/dist/extraction/vba/constants.d.ts +42 -0
- package/lib/dist/extraction/vba/constants.d.ts.map +1 -0
- package/lib/dist/extraction/vba/constants.js +112 -0
- package/lib/dist/extraction/vba/constants.js.map +1 -0
- package/lib/dist/extraction/vba/context.d.ts +175 -0
- package/lib/dist/extraction/vba/context.d.ts.map +1 -0
- package/lib/dist/extraction/vba/context.js +268 -0
- package/lib/dist/extraction/vba/context.js.map +1 -0
- package/lib/dist/extraction/vba/controls.d.ts +24 -0
- package/lib/dist/extraction/vba/controls.d.ts.map +1 -0
- package/lib/dist/extraction/vba/controls.js +89 -0
- package/lib/dist/extraction/vba/controls.js.map +1 -0
- package/lib/dist/extraction/vba/declarations.d.ts +3 -0
- package/lib/dist/extraction/vba/declarations.d.ts.map +1 -0
- package/lib/dist/extraction/vba/declarations.js +154 -0
- package/lib/dist/extraction/vba/declarations.js.map +1 -0
- package/lib/dist/extraction/vba/dims.d.ts +3 -0
- package/lib/dist/extraction/vba/dims.d.ts.map +1 -0
- package/lib/dist/extraction/vba/dims.js +186 -0
- package/lib/dist/extraction/vba/dims.js.map +1 -0
- package/lib/dist/extraction/vba/docmd.d.ts +16 -0
- package/lib/dist/extraction/vba/docmd.d.ts.map +1 -0
- package/lib/dist/extraction/vba/docmd.js +179 -0
- package/lib/dist/extraction/vba/docmd.js.map +1 -0
- package/lib/dist/extraction/vba/enums-consts.d.ts +15 -0
- package/lib/dist/extraction/vba/enums-consts.d.ts.map +1 -0
- package/lib/dist/extraction/vba/enums-consts.js +178 -0
- package/lib/dist/extraction/vba/enums-consts.js.map +1 -0
- package/lib/dist/extraction/vba/implements.d.ts +3 -0
- package/lib/dist/extraction/vba/implements.d.ts.map +1 -0
- package/lib/dist/extraction/vba/implements.js +52 -0
- package/lib/dist/extraction/vba/implements.js.map +1 -0
- package/lib/dist/extraction/vba/procedures.d.ts +3 -0
- package/lib/dist/extraction/vba/procedures.d.ts.map +1 -0
- package/lib/dist/extraction/vba/procedures.js +239 -0
- package/lib/dist/extraction/vba/procedures.js.map +1 -0
- package/lib/dist/extraction/vba/sql-wrapper.d.ts +17 -0
- package/lib/dist/extraction/vba/sql-wrapper.d.ts.map +1 -0
- package/lib/dist/extraction/vba/sql-wrapper.js +212 -0
- package/lib/dist/extraction/vba/sql-wrapper.js.map +1 -0
- package/lib/dist/extraction/vba/tempvars.d.ts +10 -0
- package/lib/dist/extraction/vba/tempvars.d.ts.map +1 -0
- package/lib/dist/extraction/vba/tempvars.js +138 -0
- package/lib/dist/extraction/vba/tempvars.js.map +1 -0
- package/lib/dist/extraction/vba/text-utils.d.ts +73 -0
- package/lib/dist/extraction/vba/text-utils.d.ts.map +1 -0
- package/lib/dist/extraction/vba/text-utils.js +195 -0
- package/lib/dist/extraction/vba/text-utils.js.map +1 -0
- package/lib/dist/extraction/vba-extractor.d.ts +3 -951
- package/lib/dist/extraction/vba-extractor.d.ts.map +1 -1
- package/lib/dist/extraction/vba-extractor.js +46 -2934
- package/lib/dist/extraction/vba-extractor.js.map +1 -1
- package/lib/dist/extraction/vba-preprocess.d.ts +1 -1
- package/lib/dist/extraction/vba-preprocess.d.ts.map +1 -1
- package/lib/dist/extraction/vba-preprocess.js +300 -88
- package/lib/dist/extraction/vba-preprocess.js.map +1 -1
- package/lib/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
- package/lib/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/lib/dist/graph/traversal.d.ts.map +1 -1
- package/lib/dist/graph/traversal.js +76 -17
- package/lib/dist/graph/traversal.js.map +1 -1
- package/lib/dist/index.d.ts +81 -1
- package/lib/dist/index.d.ts.map +1 -1
- package/lib/dist/index.js +460 -10
- package/lib/dist/index.js.map +1 -1
- package/lib/dist/installer/index.d.ts +42 -0
- package/lib/dist/installer/index.d.ts.map +1 -1
- package/lib/dist/installer/index.js +97 -2
- package/lib/dist/installer/index.js.map +1 -1
- package/lib/dist/mcp/daemon.d.ts +35 -3
- package/lib/dist/mcp/daemon.d.ts.map +1 -1
- package/lib/dist/mcp/daemon.js +101 -9
- package/lib/dist/mcp/daemon.js.map +1 -1
- package/lib/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
- package/lib/dist/mcp/dynamic-boundaries.js +2 -1
- package/lib/dist/mcp/dynamic-boundaries.js.map +1 -1
- package/lib/dist/mcp/early-ppid.d.ts +26 -0
- package/lib/dist/mcp/early-ppid.d.ts.map +1 -0
- package/lib/dist/mcp/early-ppid.js +29 -0
- package/lib/dist/mcp/early-ppid.js.map +1 -0
- package/lib/dist/mcp/index.d.ts.map +1 -1
- package/lib/dist/mcp/index.js +29 -4
- package/lib/dist/mcp/index.js.map +1 -1
- package/lib/dist/mcp/liveness-watchdog.d.ts +18 -1
- package/lib/dist/mcp/liveness-watchdog.d.ts.map +1 -1
- package/lib/dist/mcp/liveness-watchdog.js +73 -13
- package/lib/dist/mcp/liveness-watchdog.js.map +1 -1
- package/lib/dist/mcp/proxy.d.ts.map +1 -1
- package/lib/dist/mcp/proxy.js +30 -4
- package/lib/dist/mcp/proxy.js.map +1 -1
- package/lib/dist/mcp/query-pool.d.ts +14 -0
- package/lib/dist/mcp/query-pool.d.ts.map +1 -1
- package/lib/dist/mcp/query-pool.js +18 -0
- package/lib/dist/mcp/query-pool.js.map +1 -1
- package/lib/dist/mcp/session.d.ts +14 -0
- package/lib/dist/mcp/session.d.ts.map +1 -1
- package/lib/dist/mcp/session.js +28 -1
- package/lib/dist/mcp/session.js.map +1 -1
- package/lib/dist/mcp/startup-handshake.d.ts +44 -0
- package/lib/dist/mcp/startup-handshake.d.ts.map +1 -0
- package/lib/dist/mcp/startup-handshake.js +73 -0
- package/lib/dist/mcp/startup-handshake.js.map +1 -0
- package/lib/dist/mcp/tools.d.ts +22 -0
- package/lib/dist/mcp/tools.d.ts.map +1 -1
- package/lib/dist/mcp/tools.js +289 -23
- package/lib/dist/mcp/tools.js.map +1 -1
- package/lib/dist/mcp/transport.d.ts.map +1 -1
- package/lib/dist/mcp/transport.js +18 -0
- package/lib/dist/mcp/transport.js.map +1 -1
- package/lib/dist/project-config.d.ts +44 -0
- package/lib/dist/project-config.d.ts.map +1 -1
- package/lib/dist/project-config.js +151 -2
- package/lib/dist/project-config.js.map +1 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts +2 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/c-fnptr-synthesizer.js +170 -146
- package/lib/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.d.ts +1 -1
- package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/callback-synthesizer.js +1109 -97
- package/lib/dist/resolution/callback-synthesizer.js.map +1 -1
- package/lib/dist/resolution/cooperative-yield.d.ts +32 -0
- package/lib/dist/resolution/cooperative-yield.d.ts.map +1 -0
- package/lib/dist/resolution/cooperative-yield.js +42 -0
- package/lib/dist/resolution/cooperative-yield.js.map +1 -0
- package/lib/dist/resolution/frameworks/cics.d.ts +20 -0
- package/lib/dist/resolution/frameworks/cics.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/cics.js +90 -0
- package/lib/dist/resolution/frameworks/cics.js.map +1 -0
- package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/index.js +6 -0
- package/lib/dist/resolution/frameworks/index.js.map +1 -1
- package/lib/dist/resolution/frameworks/java.d.ts.map +1 -1
- package/lib/dist/resolution/frameworks/java.js +14 -6
- package/lib/dist/resolution/frameworks/java.js.map +1 -1
- package/lib/dist/resolution/frameworks/terraform.d.ts +38 -0
- package/lib/dist/resolution/frameworks/terraform.d.ts.map +1 -0
- package/lib/dist/resolution/frameworks/terraform.js +277 -0
- package/lib/dist/resolution/frameworks/terraform.js.map +1 -0
- package/lib/dist/resolution/goframe-synthesizer.d.ts +2 -1
- package/lib/dist/resolution/goframe-synthesizer.d.ts.map +1 -1
- package/lib/dist/resolution/goframe-synthesizer.js +8 -3
- package/lib/dist/resolution/goframe-synthesizer.js.map +1 -1
- package/lib/dist/resolution/import-resolver.d.ts +7 -0
- package/lib/dist/resolution/import-resolver.d.ts.map +1 -1
- package/lib/dist/resolution/import-resolver.js +129 -4
- package/lib/dist/resolution/import-resolver.js.map +1 -1
- package/lib/dist/resolution/index.d.ts +64 -2
- package/lib/dist/resolution/index.d.ts.map +1 -1
- package/lib/dist/resolution/index.js +476 -58
- package/lib/dist/resolution/index.js.map +1 -1
- package/lib/dist/resolution/name-matcher.d.ts +22 -3
- package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
- package/lib/dist/resolution/name-matcher.js +613 -39
- package/lib/dist/resolution/name-matcher.js.map +1 -1
- package/lib/dist/resolution/strip-comments.d.ts +1 -1
- package/lib/dist/resolution/strip-comments.d.ts.map +1 -1
- package/lib/dist/resolution/strip-comments.js +49 -0
- package/lib/dist/resolution/strip-comments.js.map +1 -1
- package/lib/dist/resolution/types.d.ts +29 -0
- package/lib/dist/resolution/types.d.ts.map +1 -1
- package/lib/dist/resolution/workspace-packages.d.ts +10 -0
- package/lib/dist/resolution/workspace-packages.d.ts.map +1 -1
- package/lib/dist/resolution/workspace-packages.js +142 -4
- package/lib/dist/resolution/workspace-packages.js.map +1 -1
- package/lib/dist/search/identifier-segments.d.ts +60 -0
- package/lib/dist/search/identifier-segments.d.ts.map +1 -0
- package/lib/dist/search/identifier-segments.js +176 -0
- package/lib/dist/search/identifier-segments.js.map +1 -0
- package/lib/dist/sync/git-hooks.d.ts.map +1 -1
- package/lib/dist/sync/git-hooks.js +2 -0
- package/lib/dist/sync/git-hooks.js.map +1 -1
- package/lib/dist/sync/watcher.d.ts +10 -5
- package/lib/dist/sync/watcher.d.ts.map +1 -1
- package/lib/dist/sync/watcher.js +51 -14
- package/lib/dist/sync/watcher.js.map +1 -1
- package/lib/dist/sync/worktree.d.ts +9 -0
- package/lib/dist/sync/worktree.d.ts.map +1 -1
- package/lib/dist/sync/worktree.js +45 -0
- package/lib/dist/sync/worktree.js.map +1 -1
- package/lib/dist/types.d.ts +25 -2
- package/lib/dist/types.d.ts.map +1 -1
- package/lib/dist/types.js +10 -0
- package/lib/dist/types.js.map +1 -1
- package/lib/dist/upgrade/index.d.ts +34 -2
- package/lib/dist/upgrade/index.d.ts.map +1 -1
- package/lib/dist/upgrade/index.js +164 -15
- package/lib/dist/upgrade/index.js.map +1 -1
- package/lib/dist/upgrade/remove-binary.d.ts +87 -0
- package/lib/dist/upgrade/remove-binary.d.ts.map +1 -0
- package/lib/dist/upgrade/remove-binary.js +289 -0
- package/lib/dist/upgrade/remove-binary.js.map +1 -0
- package/lib/dist/upgrade/update-check.d.ts +92 -0
- package/lib/dist/upgrade/update-check.d.ts.map +1 -0
- package/lib/dist/upgrade/update-check.js +258 -0
- package/lib/dist/upgrade/update-check.js.map +1 -0
- package/lib/node_modules/.modules.yaml +1 -1
- package/lib/node_modules/.pnpm-workspace-state-v1.json +1 -1
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/lib/dist/reasoning/config.d.ts +0 -45
- package/lib/dist/reasoning/config.d.ts.map +0 -1
- package/lib/dist/reasoning/config.js +0 -171
- package/lib/dist/reasoning/config.js.map +0 -1
- package/lib/dist/reasoning/credentials.d.ts +0 -5
- package/lib/dist/reasoning/credentials.d.ts.map +0 -1
- package/lib/dist/reasoning/credentials.js +0 -83
- package/lib/dist/reasoning/credentials.js.map +0 -1
- package/lib/dist/reasoning/login.d.ts +0 -21
- package/lib/dist/reasoning/login.d.ts.map +0 -1
- package/lib/dist/reasoning/login.js +0 -85
- package/lib/dist/reasoning/login.js.map +0 -1
- package/lib/dist/reasoning/reasoner.d.ts +0 -43
- package/lib/dist/reasoning/reasoner.d.ts.map +0 -1
- package/lib/dist/reasoning/reasoner.js +0 -308
- package/lib/dist/reasoning/reasoner.js.map +0 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.scanSqlInLine = scanSqlInLine;
|
|
4
|
+
exports.trackSqlVariableAssignment = trackSqlVariableAssignment;
|
|
5
|
+
/**
|
|
6
|
+
* SQL-in-strings sweep (REQ-CODE-8). Scans SQL wrapper calls
|
|
7
|
+
* (`DoCmd.RunSQL "…"`, `*db.OpenRecordset "…"`, `getdb().Execute "…"`) and
|
|
8
|
+
* variable-form executions, tracks `sql = sql & "…"` accumulation, and emits
|
|
9
|
+
* `references` edges (via `ctx.emitReference`) to the table names found in the
|
|
10
|
+
* FROM/JOIN/INTO/UPDATE clauses.
|
|
11
|
+
*/
|
|
12
|
+
const vba_preprocess_1 = require("../vba-preprocess");
|
|
13
|
+
const text_utils_1 = require("./text-utils");
|
|
14
|
+
/** SQL wrapper helpers — order matters because `db.Execute` is a suffix of others. */
|
|
15
|
+
const SQL_WRAPPERS = [
|
|
16
|
+
{ name: 'DoCmd.RunSQL', re: /\bDoCmd\.RunSQL\s+"((?:[^"]|"")*)"/g },
|
|
17
|
+
{ name: '*db.OpenRecordset', re: /\b(?:\p{L}[\p{L}\p{N}_]*)?db\b(?:\(\))?\.OpenRecordset\s+"((?:[^"]|"")*)"/giu },
|
|
18
|
+
{ name: '*db.Execute', re: /\b(?:\p{L}[\p{L}\p{N}_]*)?db\b(?:\(\))?\.Execute\s+"((?:[^"]|"")*)"/giu },
|
|
19
|
+
// Fix 4 (Issue #4): inline-literal forms `getdb().Execute "..."` and
|
|
20
|
+
// `getdb().OpenRecordset "..."` — the variable form is covered by
|
|
21
|
+
// SQL_VAR_EXEC_RE but the direct-literal form was missing.
|
|
22
|
+
{ name: 'getdb().Execute', re: /\bgetdb\(\)\.Execute\s+"((?:[^"]|"")*)"/g },
|
|
23
|
+
{ name: 'getdb().OpenRecordset', re: /\bgetdb\(\)\.OpenRecordset\s+"((?:[^"]|"")*)"/g },
|
|
24
|
+
];
|
|
25
|
+
/** SQL assigned to a local variable, e.g. `m_SQL = "SELECT ..." & ...`. */
|
|
26
|
+
const SQL_VAR_ASSIGN_RE = /^\s*(\p{L}[\p{L}\p{N}_]*)\s*=\s*(.*)$/iu;
|
|
27
|
+
/** SQL wrapper called with a variable, e.g. `getdb().Execute m_SQL`. */
|
|
28
|
+
const SQL_VAR_EXEC_RE = /\b(?:\p{L}[\p{L}\p{N}_]*)?db\b(?:\(\))?\.(?:OpenRecordset|Execute)\s*\(?\s*(\p{L}[\p{L}\p{N}_]*)\s*\)?/giu;
|
|
29
|
+
/**
|
|
30
|
+
* Issue #42: `DoCmd.RunSQL <identifier>` (variable form) — the dominant
|
|
31
|
+
* Access idiom for executing a dynamically-built SQL string. Today only
|
|
32
|
+
* the literal form `DoCmd.RunSQL "DELETE FROM X"` is tracked via the
|
|
33
|
+
* `SQL_WRAPPERS` regex; the variable form silently dropped table impact for
|
|
34
|
+
* every procedure that builds SQL in a string and runs it through
|
|
35
|
+
* `DoCmd.RunSQL`.
|
|
36
|
+
*
|
|
37
|
+
* This regex is the DoCmd.RunSQL analogue of `SQL_VAR_EXEC_RE` above and
|
|
38
|
+
* is iterated by `scanSqlInLine`. When a match is found, the captured
|
|
39
|
+
* identifier is resolved against `sqlVariables` (populated by
|
|
40
|
+
* `trackSqlVariableAssignment` with `&`-accumulate semantics — Issue #13)
|
|
41
|
+
* and the resulting SQL string drives `emitSqlTableReferences`.
|
|
42
|
+
*
|
|
43
|
+
* The optional `(?:\(\))?` + `\s*\(?` shape lets the regex match both
|
|
44
|
+
* the parenthesised form `DoCmd.RunSQL(strSQL)` and the no-paren form
|
|
45
|
+
* `DoCmd.RunSQL strSQL` that the existing SQL_WRAPPERS literal regex
|
|
46
|
+
* does not cover. The captured identifier is the only thing we need —
|
|
47
|
+
* we DO NOT try to parse what the variable points at; that's the
|
|
48
|
+
* existing `sqlVariables` map's job.
|
|
49
|
+
*/
|
|
50
|
+
const SQL_VAR_DOCMD_RUNSQL_RE = /\bDoCmd\.RunSQL\s*\(?\s*(\p{L}[\p{L}\p{N}_]*)\s*\)?/giu;
|
|
51
|
+
/**
|
|
52
|
+
* SQL table-name regex scoped to the clauses that introduce a table
|
|
53
|
+
* reference: `FROM <t>`, `JOIN <t>`, `INTO <t>`, `UPDATE <t>`. Adding
|
|
54
|
+
* `JOIN` lets the scanner pick up tables from joined fragments that
|
|
55
|
+
* arrive via `&`-concatenated wrapper literals (e.g.
|
|
56
|
+
* `db.Execute "FROM A" & " JOIN B"`); without it the second literal's
|
|
57
|
+
* table was silently dropped even though the wrapper regex now matches
|
|
58
|
+
* the chain.
|
|
59
|
+
*
|
|
60
|
+
* The captured table name is an optional bracketed/unbracketed schema
|
|
61
|
+
* prefix followed by a `.`, then a bracketed-or-bare identifier — so
|
|
62
|
+
* `FROM dbo.tblCustomers` and `FROM [My Schema].[My Table]` come
|
|
63
|
+
* through as one composite reference. Without the prefix the regex
|
|
64
|
+
* still matches a single identifier byte-identical to the old shape.
|
|
65
|
+
* Brackets in the captured composite are stripped by
|
|
66
|
+
* `emitSqlTableReferences` (`replace(/[\[\]]/g, '')`), so the public
|
|
67
|
+
* node name is the unwrapped form `dbo.tblCustomers` /
|
|
68
|
+
* `My Schema.My Table` — matching how plain `[Order Details]` is also
|
|
69
|
+
* unwrapped to `Order Details`. The identifier class
|
|
70
|
+
* `\[[^\]]+\]|\p{L}[\p{L}\p{N}_]*` (same as the saved-queries
|
|
71
|
+
* `TABLE_RE` in `sql-query-extractor.ts`) ensures bracketed names
|
|
72
|
+
* with spaces — `[Order Details]`, `[My Schema]`, `[My Table]` —
|
|
73
|
+
* are captured whole.
|
|
74
|
+
*/
|
|
75
|
+
const SQL_TABLE_RE = /\b(?:FROM|JOIN|INTO|UPDATE)\s+((?:(?:\[[^\]]+\]|\p{L}[\p{L}\p{N}_]*)\.)?(?:\[[^\]]+\]|\p{L}[\p{L}\p{N}_]*))/giu;
|
|
76
|
+
/**
|
|
77
|
+
* Regex matching the chained `& "..."` literals that may follow a
|
|
78
|
+
* wrapper's first literal on the same physical line. Captures the
|
|
79
|
+
* literal CONTENT (group 1); the surrounding `&` and quotes are
|
|
80
|
+
* structural, not data. VBA allows whitespace around `&` and around
|
|
81
|
+
* the inner quotes — handled with `\s*`. The `((?:[^"]|"")*)` body
|
|
82
|
+
* mirrors the wrapper regex so a `""` inside a chained literal still
|
|
83
|
+
* decodes to a single `"`.
|
|
84
|
+
*
|
|
85
|
+
* Cross-physical-line concat via `_` continuation is OUT OF SCOPE for
|
|
86
|
+
* v1 (deferred; see commit message).
|
|
87
|
+
*/
|
|
88
|
+
const SQL_WRAPPER_CHAIN_RE = /&\s*"((?:[^"]|"")*)"/g;
|
|
89
|
+
/**
|
|
90
|
+
* Given the text that follows a SQL wrapper's first literal on the same
|
|
91
|
+
* physical line, return the contents of every `& "..."` chained literal
|
|
92
|
+
* in source order. Operates per-physical-line only — VBA `_` line
|
|
93
|
+
* continuation across physical lines is handled separately by
|
|
94
|
+
* `collectStringLiteralText` for the variable-assignment path.
|
|
95
|
+
*/
|
|
96
|
+
function collectSqlWrapperChain(rest) {
|
|
97
|
+
const out = [];
|
|
98
|
+
const re = new RegExp(SQL_WRAPPER_CHAIN_RE.source, SQL_WRAPPER_CHAIN_RE.flags);
|
|
99
|
+
let m;
|
|
100
|
+
while ((m = re.exec(rest)) !== null) {
|
|
101
|
+
out.push(m[1] ?? '');
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
function scanSqlInLine(ctx, line, lineNum, dedupe, sqlVariables) {
|
|
106
|
+
for (const { re } of SQL_WRAPPERS) {
|
|
107
|
+
// Each wrapper regex is stateful (has /g); reset before use.
|
|
108
|
+
const localRe = new RegExp(re.source, re.flags);
|
|
109
|
+
let m;
|
|
110
|
+
while ((m = localRe.exec(line)) !== null) {
|
|
111
|
+
const firstLiteral = m[1] ?? '';
|
|
112
|
+
// After the wrapper regex consumes up to and including the closing
|
|
113
|
+
// `"` of the first literal, walk the rest of the line for any
|
|
114
|
+
// `& "..."` chains and concatenate every literal's content. Joining
|
|
115
|
+
// with a space (mirrors `collectStringLiteralText`) keeps adjacent
|
|
116
|
+
// `FROM tblA` & `FROM tblB` separated so `SQL_TABLE_RE` finds both.
|
|
117
|
+
const rest = line.slice(m.index + m[0].length);
|
|
118
|
+
const chain = collectSqlWrapperChain(rest);
|
|
119
|
+
const joined = [firstLiteral, ...chain].join(' ');
|
|
120
|
+
emitSqlTableReferences(ctx, joined, lineNum, dedupe);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const localRe = new RegExp(SQL_VAR_EXEC_RE.source, SQL_VAR_EXEC_RE.flags);
|
|
124
|
+
let vm;
|
|
125
|
+
while ((vm = localRe.exec(line)) !== null) {
|
|
126
|
+
const varName = (vm[1] ?? '').toLowerCase();
|
|
127
|
+
const sqlString = sqlVariables.get(varName);
|
|
128
|
+
if (!sqlString)
|
|
129
|
+
continue;
|
|
130
|
+
emitSqlTableReferences(ctx, sqlString, lineNum, dedupe);
|
|
131
|
+
}
|
|
132
|
+
// Issue #42: `DoCmd.RunSQL <identifier>` (variable form). Mirrors the
|
|
133
|
+
// SQL_VAR_EXEC_RE path above but for the Access-style `DoCmd.RunSQL`
|
|
134
|
+
// idiom — the dominant pattern in real-world VBA modules. Resolve the
|
|
135
|
+
// captured identifier against `sqlVariables` (populated by
|
|
136
|
+
// `trackSqlVariableAssignment` with `&`-accumulate semantics, Issue
|
|
137
|
+
// #13) and feed the resolved SQL string into `emitSqlTableReferences`.
|
|
138
|
+
// Unresolved identifiers (no row in the map) are silently skipped —
|
|
139
|
+
// same graceful-no-op contract as SQL_VAR_EXEC_RE.
|
|
140
|
+
const docmdLocalRe = new RegExp(SQL_VAR_DOCMD_RUNSQL_RE.source, SQL_VAR_DOCMD_RUNSQL_RE.flags);
|
|
141
|
+
let dm;
|
|
142
|
+
while ((dm = docmdLocalRe.exec(line)) !== null) {
|
|
143
|
+
const varName = (dm[1] ?? '').toLowerCase();
|
|
144
|
+
const sqlString = sqlVariables.get(varName);
|
|
145
|
+
if (!sqlString)
|
|
146
|
+
continue;
|
|
147
|
+
emitSqlTableReferences(ctx, sqlString, lineNum, dedupe);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* #13 fix: `sql = sql & "..."` (self-referential concatenation) must
|
|
152
|
+
* ACCUMULATE the new fragment onto whatever was already tracked for
|
|
153
|
+
* `varName`, not overwrite it. Overwriting silently dropped earlier
|
|
154
|
+
* fragments' tables — typically the initial `FROM <table>` in
|
|
155
|
+
* `sql = "SELECT * FROM tblA"` followed by `sql = sql & " WHERE x=1"`.
|
|
156
|
+
*
|
|
157
|
+
* Detection: the RHS (`m[2]`, trimmed) starts with `<varName> &`,
|
|
158
|
+
* case-insensitively — matching VBA's case-insensitive identifiers (`Sql`
|
|
159
|
+
* and `sql` are the same variable). A genuine fresh assignment (RHS does
|
|
160
|
+
* NOT start with the self-reference) still RESETS tracking — that
|
|
161
|
+
* behavior is unchanged.
|
|
162
|
+
*/
|
|
163
|
+
function trackSqlVariableAssignment(lines, lineIndex, sqlVariables) {
|
|
164
|
+
const line = lines[lineIndex] ?? '';
|
|
165
|
+
const m = SQL_VAR_ASSIGN_RE.exec(line);
|
|
166
|
+
if (!m)
|
|
167
|
+
return;
|
|
168
|
+
const rawVarName = m[1] ?? '';
|
|
169
|
+
const varName = rawVarName.toLowerCase();
|
|
170
|
+
const rhs = (m[2] ?? '').trim();
|
|
171
|
+
const newFragment = collectStringLiteralText(lines, lineIndex);
|
|
172
|
+
if (!newFragment)
|
|
173
|
+
return;
|
|
174
|
+
const selfRefRe = new RegExp(`^${(0, text_utils_1.escapeRegExpLiteral)(rawVarName)}\\s*&`, 'i');
|
|
175
|
+
const existing = sqlVariables.get(varName);
|
|
176
|
+
if (existing !== undefined && selfRefRe.test(rhs)) {
|
|
177
|
+
sqlVariables.set(varName, `${existing} ${newFragment}`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
sqlVariables.set(varName, newFragment);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function collectStringLiteralText(lines, startIndex) {
|
|
184
|
+
const fragments = [];
|
|
185
|
+
for (let i = startIndex; i < lines.length; i++) {
|
|
186
|
+
const line = lines[i] ?? '';
|
|
187
|
+
for (const lit of (0, vba_preprocess_1.extractStringLiterals)(line)) {
|
|
188
|
+
fragments.push(lit.text);
|
|
189
|
+
}
|
|
190
|
+
if (!line.trimEnd().endsWith('&'))
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
return fragments.join(' ');
|
|
194
|
+
}
|
|
195
|
+
function emitSqlTableReferences(ctx, sqlString, lineNum, dedupe) {
|
|
196
|
+
// Scan the SQL string for FROM/INTO/UPDATE <table>.
|
|
197
|
+
// Preserve the source regex's `/u` flag (Unicode property classes)
|
|
198
|
+
// — hardcoding `'gi'` here would silently break non-ASCII identifiers.
|
|
199
|
+
const tableRe = new RegExp(SQL_TABLE_RE.source, SQL_TABLE_RE.flags);
|
|
200
|
+
let tm;
|
|
201
|
+
while ((tm = tableRe.exec(sqlString)) !== null) {
|
|
202
|
+
const table = (tm[1] ?? '').replace(/[\[\]]/g, '');
|
|
203
|
+
if (!table)
|
|
204
|
+
continue;
|
|
205
|
+
const key = `${lineNum}:${table}`;
|
|
206
|
+
if (dedupe.has(key))
|
|
207
|
+
continue;
|
|
208
|
+
dedupe.add(key);
|
|
209
|
+
ctx.emitReference(table, lineNum, 0, 'vba-sql-table');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=sql-wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-wrapper.js","sourceRoot":"","sources":["../../../src/extraction/vba/sql-wrapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { VbaExtractorContext, ProcInfo } from './context';
|
|
2
|
+
/**
|
|
3
|
+
* Issue #50: scan one line of VBA source for TempVars access sites and
|
|
4
|
+
* emit one `references` edge per site. Bang form scans the MASKED line,
|
|
5
|
+
* paren + Add forms scan the ORIGINAL line. Access is classified by the
|
|
6
|
+
* line suffix after the match: a bare `=` next non-whitespace char is a
|
|
7
|
+
* write (VBA has no `==`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function sweepTempVars(ctx: VbaExtractorContext, maskedLine: string, originalLine: string, lineNum: number, caller: ProcInfo | undefined): void;
|
|
10
|
+
//# sourceMappingURL=tempvars.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tempvars.d.ts","sourceRoot":"","sources":["../../../src/extraction/vba/tempvars.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAmG1D;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,mBAAmB,EACxB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,QAAQ,GAAG,SAAS,GAC3B,IAAI,CAiCN"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sweepTempVars = sweepTempVars;
|
|
4
|
+
/**
|
|
5
|
+
* TempVars sweep (issue #50). Models each STATIC-LITERAL Access TempVars key
|
|
6
|
+
* as a synthetic `class` placeholder node (cross-file id-stable) and emits one
|
|
7
|
+
* `references` edge per reading/writing procedure with
|
|
8
|
+
* `metadata.synthesizedBy: 'vba-tempvar'` and `metadata.access` ∈ {read, write}.
|
|
9
|
+
*/
|
|
10
|
+
const tree_sitter_helpers_1 = require("../tree-sitter-helpers");
|
|
11
|
+
const text_utils_1 = require("./text-utils");
|
|
12
|
+
/**
|
|
13
|
+
* Issue #50: TempVars — Access's global key-value store for cross-form
|
|
14
|
+
* state. Three scanner surfaces cover the four real idioms:
|
|
15
|
+
* - `TEMP_VAR_BANG_RE` — `TempVars!clave` (no parens; write or read)
|
|
16
|
+
* - `TEMP_VAR_PAREN_RE` — `TempVars("clave")` (parens; write or read)
|
|
17
|
+
* - `TEMP_VAR_ADD_RE` — `TempVars.Add "clave", v` (always a write)
|
|
18
|
+
*
|
|
19
|
+
* Bang vs paren split by line-source: the bang form has no string literals
|
|
20
|
+
* in scope, so we scan the MASKED line (`maskStringContent` replaces
|
|
21
|
+
* `"…"` content with spaces). The paren and Add forms have their key INSIDE
|
|
22
|
+
* a `"…"` literal that gets blanked by the masker, so those regexes scan
|
|
23
|
+
* the ORIGINAL (unmasked) line.
|
|
24
|
+
*
|
|
25
|
+
* Dynamic-key forms — `TempVars(strNombre)`, `TempVars("clave" & suffix)` —
|
|
26
|
+
* are silently unmatched by all three regexes (none tolerate a function-call
|
|
27
|
+
* or `&` arg). REQ-CODE-4 "unresolvable is silent" applies.
|
|
28
|
+
*/
|
|
29
|
+
const TEMP_VAR_BANG_RE = /\bTempVars!\s*(\p{L}[\p{L}\p{N}_]*)/gu;
|
|
30
|
+
/**
|
|
31
|
+
* Issue #50 (cont.):
|
|
32
|
+
* `TempVars("clave")` / `TempVars( "clave" )` capture. Scanned
|
|
33
|
+
* over the original (unmasked) line — the literal lives INSIDE a
|
|
34
|
+
* string and would be stripped by `maskStringContent`.
|
|
35
|
+
*/
|
|
36
|
+
const TEMP_VAR_PAREN_RE = /\bTempVars\s*\(\s*"([^"]+)"\s*\)/gu;
|
|
37
|
+
/**
|
|
38
|
+
* Issue #50 (cont.):
|
|
39
|
+
* `TempVars.Add "clave", value` capture. Always a write (the
|
|
40
|
+
* `.Add` method inserts/updates the entry). Scanned over the
|
|
41
|
+
* original (unmasked) line for the same string-literal reason as
|
|
42
|
+
* `TEMP_VAR_PAREN_RE`.
|
|
43
|
+
*/
|
|
44
|
+
const TEMP_VAR_ADD_RE = /\bTempVars\.Add\s+"([^"]+)"\s*,/gi;
|
|
45
|
+
/**
|
|
46
|
+
* Issue #50: emit one TempVar reading/writing site. Per call:
|
|
47
|
+
* - placeholder `class` node keyed on the synthetic
|
|
48
|
+
* `synthetic:tempvar/<key>` file path so cross-file extraction
|
|
49
|
+
* calls collapse to one node per key,
|
|
50
|
+
* - `references` edge from the calling `function` node
|
|
51
|
+
* (via `findOrCreateFunctionNodeId`) carrying
|
|
52
|
+
* `metadata.synthesizedBy: 'vba-tempvar'` AND
|
|
53
|
+
* `metadata.access: 'read' | 'write'`.
|
|
54
|
+
*
|
|
55
|
+
* Skips when there is no caller (module-level code) — REQ-CODE-4
|
|
56
|
+
* "unresolvable/runtime reference is silent".
|
|
57
|
+
*/
|
|
58
|
+
function emitTempVarReference(ctx, caller, key, lineNum, column, access) {
|
|
59
|
+
if (!caller)
|
|
60
|
+
return;
|
|
61
|
+
if (!key)
|
|
62
|
+
return;
|
|
63
|
+
const syntheticFilePath = `synthetic:tempvar/${key}`;
|
|
64
|
+
const targetId = (0, tree_sitter_helpers_1.generateNodeId)(syntheticFilePath, 'class', // placeholder kind — see SQL_TABLE_RE emitReference for precedent
|
|
65
|
+
key, 0);
|
|
66
|
+
if (!ctx.synthTempVarNodeIds.has(targetId)) {
|
|
67
|
+
ctx.synthTempVarNodeIds.add(targetId);
|
|
68
|
+
ctx.nodes.push({
|
|
69
|
+
id: targetId,
|
|
70
|
+
kind: 'class',
|
|
71
|
+
name: key,
|
|
72
|
+
qualifiedName: key,
|
|
73
|
+
filePath: syntheticFilePath,
|
|
74
|
+
language: 'vba',
|
|
75
|
+
startLine: lineNum,
|
|
76
|
+
endLine: lineNum,
|
|
77
|
+
startColumn: column,
|
|
78
|
+
endColumn: column + key.length,
|
|
79
|
+
updatedAt: Date.now(),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
ctx.edges.push({
|
|
83
|
+
source: ctx.findOrCreateFunctionNodeId(caller),
|
|
84
|
+
target: targetId,
|
|
85
|
+
kind: 'references',
|
|
86
|
+
provenance: 'heuristic',
|
|
87
|
+
metadata: {
|
|
88
|
+
synthesizedBy: 'vba-tempvar',
|
|
89
|
+
// User-facing enum: lowercase single-token string values.
|
|
90
|
+
access,
|
|
91
|
+
},
|
|
92
|
+
line: lineNum,
|
|
93
|
+
column,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Issue #50: scan one line of VBA source for TempVars access sites and
|
|
98
|
+
* emit one `references` edge per site. Bang form scans the MASKED line,
|
|
99
|
+
* paren + Add forms scan the ORIGINAL line. Access is classified by the
|
|
100
|
+
* line suffix after the match: a bare `=` next non-whitespace char is a
|
|
101
|
+
* write (VBA has no `==`).
|
|
102
|
+
*/
|
|
103
|
+
function sweepTempVars(ctx, maskedLine, originalLine, lineNum, caller) {
|
|
104
|
+
// 1) Bang form — masked line. No string-literal interaction.
|
|
105
|
+
const bangRe = new RegExp(TEMP_VAR_BANG_RE.source, TEMP_VAR_BANG_RE.flags);
|
|
106
|
+
let bm;
|
|
107
|
+
while ((bm = bangRe.exec(maskedLine)) !== null) {
|
|
108
|
+
const key = bm[1] ?? '';
|
|
109
|
+
if (!key)
|
|
110
|
+
continue;
|
|
111
|
+
const access = (0, text_utils_1.detectAssignmentSuffix)(maskedLine, bm.index + bm[0].length)
|
|
112
|
+
? 'write'
|
|
113
|
+
: 'read';
|
|
114
|
+
emitTempVarReference(ctx, caller, key, lineNum, bm.index, access);
|
|
115
|
+
}
|
|
116
|
+
// 2) Paren form — original line. The literal survives only here.
|
|
117
|
+
const parenRe = new RegExp(TEMP_VAR_PAREN_RE.source, TEMP_VAR_PAREN_RE.flags);
|
|
118
|
+
let pm;
|
|
119
|
+
while ((pm = parenRe.exec(originalLine)) !== null) {
|
|
120
|
+
const key = pm[1] ?? '';
|
|
121
|
+
if (!key)
|
|
122
|
+
continue;
|
|
123
|
+
const access = (0, text_utils_1.detectAssignmentSuffix)(originalLine, pm.index + pm[0].length)
|
|
124
|
+
? 'write'
|
|
125
|
+
: 'read';
|
|
126
|
+
emitTempVarReference(ctx, caller, key, lineNum, pm.index, access);
|
|
127
|
+
}
|
|
128
|
+
// 3) Add form — original line. Always a write.
|
|
129
|
+
const addRe = new RegExp(TEMP_VAR_ADD_RE.source, TEMP_VAR_ADD_RE.flags);
|
|
130
|
+
let am;
|
|
131
|
+
while ((am = addRe.exec(originalLine)) !== null) {
|
|
132
|
+
const key = am[1] ?? '';
|
|
133
|
+
if (!key)
|
|
134
|
+
continue;
|
|
135
|
+
emitTempVarReference(ctx, caller, key, lineNum, am.index, 'write');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=tempvars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tempvars.js","sourceRoot":"","sources":["../../../src/extraction/vba/tempvars.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure text helpers shared across the VBA extraction passes. None of these
|
|
3
|
+
* touch extractor state — they are deterministic string transforms lifted
|
|
4
|
+
* out of `VbaExtractor` verbatim so each pass module can import what it needs
|
|
5
|
+
* without pulling in the orchestrator.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Fold a VBA visibility keyword to the canonical lowercase enum, matching
|
|
9
|
+
* the procedure convention: `Private` → 'private'; `Public`, `Global`,
|
|
10
|
+
* `Friend`, or none → 'public' (VBA's default module-level `Const`/`Enum`
|
|
11
|
+
* is Private, but we follow the same broader-than-private fold the proc
|
|
12
|
+
* sweep uses so visibility is consistent across symbol kinds).
|
|
13
|
+
*/
|
|
14
|
+
export declare function foldVisibility(raw: string): 'public' | 'private';
|
|
15
|
+
/**
|
|
16
|
+
* Fix 2 (Issue #2): replace string-literal content with spaces so that
|
|
17
|
+
* call-site patterns inside `"..."` spans are invisible to CALL_RE and
|
|
18
|
+
* the statement-form detectors. Column positions are preserved (each
|
|
19
|
+
* character is replaced 1-for-1) so any col-based metadata stays correct.
|
|
20
|
+
*/
|
|
21
|
+
export declare function maskStringContent(line: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* #13 helper: escape a variable name for safe interpolation into the
|
|
24
|
+
* self-reference RegExp built by `trackSqlVariableAssignment`. VBA
|
|
25
|
+
* identifiers are alphanumeric+underscore only, so in practice nothing here
|
|
26
|
+
* ever needs escaping — this guards against regex metacharacters anyway
|
|
27
|
+
* rather than assume the input is always well-formed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function escapeRegExpLiteral(value: string): string;
|
|
30
|
+
export declare function parseConstDeclarations(body: string): Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
value: string | null;
|
|
33
|
+
}>;
|
|
34
|
+
export declare function splitOutsideVbaStrings(value: string, separator: string): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Issue #50 helper: return true iff `line.charAt(fromIndex..)` (after the
|
|
37
|
+
* matched TempVars site, including any trailing whitespace) holds an `=`
|
|
38
|
+
* (write-assignment) and not a `==` (VBA has no `==` operator, so a bare
|
|
39
|
+
* check for `=` is safe). Used by `sweepTempVars` to classify a `TempVars`
|
|
40
|
+
* access as read vs write from the local line context.
|
|
41
|
+
*
|
|
42
|
+
* We skip over trailing whitespace only — `.`, `(`, `<`, `>`, `*`, `+`
|
|
43
|
+
* etc. all mean "this isn't an assignment target", and bare `=`
|
|
44
|
+
* is the only access-suffix shape VBA syntax allows here. A line like
|
|
45
|
+
* `TempVars!x = 1` (write) or `Debug.Print TempVars!x` (read) land in
|
|
46
|
+
* the right bucket without further analysis.
|
|
47
|
+
*
|
|
48
|
+
* Strings should already be masked out of `line` (`maskStringContent`)
|
|
49
|
+
* when this is called for the bang form (no string in scope anyway);
|
|
50
|
+
* the paren form passes the ORIGINAL line — but for THAT form the
|
|
51
|
+
* captured match ends at the closing `"` of the literal, so any `=`
|
|
52
|
+
* that follows is unambiguously outside the string.
|
|
53
|
+
*/
|
|
54
|
+
export declare function detectAssignmentSuffix(line: string, fromIndex: number): boolean;
|
|
55
|
+
export declare function unwrapVbaStringLiteral(raw: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Hueco 3 helper: parse an Access event-handler Sub name into its
|
|
58
|
+
* `<ControlName>_<EventName>` components. Returns null when the name does
|
|
59
|
+
* not match the convention, when the split yields an empty segment, or
|
|
60
|
+
* when the control name is `Form` (form-level events are NOT control
|
|
61
|
+
* handlers — `Form_Load` is the form's own lifecycle event, not a
|
|
62
|
+
* command-button click).
|
|
63
|
+
*
|
|
64
|
+
* Splitting on the LAST underscore (rather than the first) lets
|
|
65
|
+
* multi-word event names parse correctly: `ComandoAltaPM_BeforeDelConfirm`
|
|
66
|
+
* yields control=`ComandoAltaPM`, event=`BeforeDelConfirm`, not
|
|
67
|
+
* control=`ComandoAlta`, event=`PM_BeforeDelConfirm`.
|
|
68
|
+
*/
|
|
69
|
+
export declare function parseEventHandlerName(name: string): {
|
|
70
|
+
controlName: string;
|
|
71
|
+
eventName: string;
|
|
72
|
+
} | null;
|
|
73
|
+
//# sourceMappingURL=text-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-utils.d.ts","sourceRoot":"","sources":["../../../src/extraction/vba/text-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4BtD;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,GACX,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAc/C;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BjF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAW/E;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgB1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GACX;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAUnD"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pure text helpers shared across the VBA extraction passes. None of these
|
|
4
|
+
* touch extractor state — they are deterministic string transforms lifted
|
|
5
|
+
* out of `VbaExtractor` verbatim so each pass module can import what it needs
|
|
6
|
+
* without pulling in the orchestrator.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.foldVisibility = foldVisibility;
|
|
10
|
+
exports.maskStringContent = maskStringContent;
|
|
11
|
+
exports.escapeRegExpLiteral = escapeRegExpLiteral;
|
|
12
|
+
exports.parseConstDeclarations = parseConstDeclarations;
|
|
13
|
+
exports.splitOutsideVbaStrings = splitOutsideVbaStrings;
|
|
14
|
+
exports.detectAssignmentSuffix = detectAssignmentSuffix;
|
|
15
|
+
exports.unwrapVbaStringLiteral = unwrapVbaStringLiteral;
|
|
16
|
+
exports.parseEventHandlerName = parseEventHandlerName;
|
|
17
|
+
/**
|
|
18
|
+
* Fold a VBA visibility keyword to the canonical lowercase enum, matching
|
|
19
|
+
* the procedure convention: `Private` → 'private'; `Public`, `Global`,
|
|
20
|
+
* `Friend`, or none → 'public' (VBA's default module-level `Const`/`Enum`
|
|
21
|
+
* is Private, but we follow the same broader-than-private fold the proc
|
|
22
|
+
* sweep uses so visibility is consistent across symbol kinds).
|
|
23
|
+
*/
|
|
24
|
+
function foldVisibility(raw) {
|
|
25
|
+
return raw.trim().toLowerCase() === 'private' ? 'private' : 'public';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fix 2 (Issue #2): replace string-literal content with spaces so that
|
|
29
|
+
* call-site patterns inside `"..."` spans are invisible to CALL_RE and
|
|
30
|
+
* the statement-form detectors. Column positions are preserved (each
|
|
31
|
+
* character is replaced 1-for-1) so any col-based metadata stays correct.
|
|
32
|
+
*/
|
|
33
|
+
function maskStringContent(line) {
|
|
34
|
+
let result = '';
|
|
35
|
+
let i = 0;
|
|
36
|
+
while (i < line.length) {
|
|
37
|
+
const ch = line[i];
|
|
38
|
+
if (ch === '"') {
|
|
39
|
+
result += ' '; // opening quote masked
|
|
40
|
+
i++;
|
|
41
|
+
while (i < line.length) {
|
|
42
|
+
const c = line[i];
|
|
43
|
+
if (c === '"' && line[i + 1] === '"') {
|
|
44
|
+
result += ' '; // doubled-quote escape masked (2 chars)
|
|
45
|
+
i += 2;
|
|
46
|
+
}
|
|
47
|
+
else if (c === '"') {
|
|
48
|
+
result += ' '; // closing quote masked
|
|
49
|
+
i++;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
result += ' '; // string content → space
|
|
54
|
+
i++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
result += ch;
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* #13 helper: escape a variable name for safe interpolation into the
|
|
67
|
+
* self-reference RegExp built by `trackSqlVariableAssignment`. VBA
|
|
68
|
+
* identifiers are alphanumeric+underscore only, so in practice nothing here
|
|
69
|
+
* ever needs escaping — this guards against regex metacharacters anyway
|
|
70
|
+
* rather than assume the input is always well-formed.
|
|
71
|
+
*/
|
|
72
|
+
function escapeRegExpLiteral(value) {
|
|
73
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
74
|
+
}
|
|
75
|
+
function parseConstDeclarations(body) {
|
|
76
|
+
const declarations = [];
|
|
77
|
+
for (const part of splitOutsideVbaStrings(body, ',')) {
|
|
78
|
+
const m = /^\s*(\p{L}[\p{L}\p{N}_]*)\s*(?:As\s+[^=]+?)?\s*=\s*(.+?)\s*$/iu.exec(part);
|
|
79
|
+
if (!m)
|
|
80
|
+
continue;
|
|
81
|
+
const name = m[1] ?? '';
|
|
82
|
+
const rawValue = (m[2] ?? '').trim();
|
|
83
|
+
declarations.push({
|
|
84
|
+
name,
|
|
85
|
+
value: rawValue.startsWith('"') ? unwrapVbaStringLiteral(rawValue) : rawValue || null,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return declarations;
|
|
89
|
+
}
|
|
90
|
+
function splitOutsideVbaStrings(value, separator) {
|
|
91
|
+
const parts = [];
|
|
92
|
+
let current = '';
|
|
93
|
+
let inString = false;
|
|
94
|
+
for (let i = 0; i < value.length; i++) {
|
|
95
|
+
const ch = value[i];
|
|
96
|
+
const next = value[i + 1];
|
|
97
|
+
if (ch === '"') {
|
|
98
|
+
current += ch;
|
|
99
|
+
if (inString && next === '"') {
|
|
100
|
+
current += next;
|
|
101
|
+
i++;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
inString = !inString;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (!inString && ch === separator) {
|
|
108
|
+
parts.push(current);
|
|
109
|
+
current = '';
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
current += ch;
|
|
113
|
+
}
|
|
114
|
+
parts.push(current);
|
|
115
|
+
return parts;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Issue #50 helper: return true iff `line.charAt(fromIndex..)` (after the
|
|
119
|
+
* matched TempVars site, including any trailing whitespace) holds an `=`
|
|
120
|
+
* (write-assignment) and not a `==` (VBA has no `==` operator, so a bare
|
|
121
|
+
* check for `=` is safe). Used by `sweepTempVars` to classify a `TempVars`
|
|
122
|
+
* access as read vs write from the local line context.
|
|
123
|
+
*
|
|
124
|
+
* We skip over trailing whitespace only — `.`, `(`, `<`, `>`, `*`, `+`
|
|
125
|
+
* etc. all mean "this isn't an assignment target", and bare `=`
|
|
126
|
+
* is the only access-suffix shape VBA syntax allows here. A line like
|
|
127
|
+
* `TempVars!x = 1` (write) or `Debug.Print TempVars!x` (read) land in
|
|
128
|
+
* the right bucket without further analysis.
|
|
129
|
+
*
|
|
130
|
+
* Strings should already be masked out of `line` (`maskStringContent`)
|
|
131
|
+
* when this is called for the bang form (no string in scope anyway);
|
|
132
|
+
* the paren form passes the ORIGINAL line — but for THAT form the
|
|
133
|
+
* captured match ends at the closing `"` of the literal, so any `=`
|
|
134
|
+
* that follows is unambiguously outside the string.
|
|
135
|
+
*/
|
|
136
|
+
function detectAssignmentSuffix(line, fromIndex) {
|
|
137
|
+
let i = fromIndex;
|
|
138
|
+
while (i < line.length) {
|
|
139
|
+
const ch = line[i];
|
|
140
|
+
if (ch === ' ' || ch === '\t') {
|
|
141
|
+
i++;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
return ch === '=';
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
function unwrapVbaStringLiteral(raw) {
|
|
149
|
+
const trimmed = raw.trim();
|
|
150
|
+
if (!trimmed.startsWith('"'))
|
|
151
|
+
return trimmed;
|
|
152
|
+
let text = '';
|
|
153
|
+
for (let i = 1; i < trimmed.length; i++) {
|
|
154
|
+
const ch = trimmed[i];
|
|
155
|
+
const next = trimmed[i + 1];
|
|
156
|
+
if (ch === '"' && next === '"') {
|
|
157
|
+
text += '"';
|
|
158
|
+
i++;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (ch === '"')
|
|
162
|
+
break;
|
|
163
|
+
text += ch;
|
|
164
|
+
}
|
|
165
|
+
return text;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Hueco 3 helper: parse an Access event-handler Sub name into its
|
|
169
|
+
* `<ControlName>_<EventName>` components. Returns null when the name does
|
|
170
|
+
* not match the convention, when the split yields an empty segment, or
|
|
171
|
+
* when the control name is `Form` (form-level events are NOT control
|
|
172
|
+
* handlers — `Form_Load` is the form's own lifecycle event, not a
|
|
173
|
+
* command-button click).
|
|
174
|
+
*
|
|
175
|
+
* Splitting on the LAST underscore (rather than the first) lets
|
|
176
|
+
* multi-word event names parse correctly: `ComandoAltaPM_BeforeDelConfirm`
|
|
177
|
+
* yields control=`ComandoAltaPM`, event=`BeforeDelConfirm`, not
|
|
178
|
+
* control=`ComandoAlta`, event=`PM_BeforeDelConfirm`.
|
|
179
|
+
*/
|
|
180
|
+
function parseEventHandlerName(name) {
|
|
181
|
+
if (!name)
|
|
182
|
+
return null;
|
|
183
|
+
const lastUnderscore = name.lastIndexOf('_');
|
|
184
|
+
if (lastUnderscore <= 0)
|
|
185
|
+
return null; // no underscore OR starts with underscore
|
|
186
|
+
const controlName = name.slice(0, lastUnderscore);
|
|
187
|
+
const eventName = name.slice(lastUnderscore + 1);
|
|
188
|
+
if (!controlName || !eventName)
|
|
189
|
+
return null;
|
|
190
|
+
// Form-level events live on the form, not on a control.
|
|
191
|
+
if (controlName.toLowerCase() === 'form')
|
|
192
|
+
return null;
|
|
193
|
+
return { controlName, eventName };
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=text-utils.js.map
|