@grafema/core 0.1.0-alpha.5 → 0.1.1-alpha

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 (391) hide show
  1. package/README.md +0 -1
  2. package/dist/Orchestrator.d.ts +24 -2
  3. package/dist/Orchestrator.d.ts.map +1 -1
  4. package/dist/Orchestrator.js +197 -24
  5. package/dist/config/ConfigLoader.d.ts +72 -0
  6. package/dist/config/ConfigLoader.d.ts.map +1 -0
  7. package/dist/config/ConfigLoader.js +187 -0
  8. package/dist/config/index.d.ts +6 -0
  9. package/dist/config/index.d.ts.map +1 -0
  10. package/dist/config/index.js +4 -0
  11. package/dist/core/ASTWorker.d.ts +11 -36
  12. package/dist/core/ASTWorker.d.ts.map +1 -1
  13. package/dist/core/ASTWorker.js +93 -99
  14. package/dist/core/CoverageAnalyzer.d.ts +65 -0
  15. package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
  16. package/dist/core/CoverageAnalyzer.js +198 -0
  17. package/dist/core/FileNodeManager.d.ts +40 -0
  18. package/dist/core/FileNodeManager.d.ts.map +1 -0
  19. package/dist/core/FileNodeManager.js +84 -0
  20. package/dist/core/GraphFreshnessChecker.d.ts +33 -0
  21. package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
  22. package/dist/core/GraphFreshnessChecker.js +101 -0
  23. package/dist/core/HashUtils.d.ts +24 -0
  24. package/dist/core/HashUtils.d.ts.map +1 -0
  25. package/dist/core/HashUtils.js +45 -0
  26. package/dist/core/IncrementalReanalyzer.d.ts +36 -0
  27. package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
  28. package/dist/core/IncrementalReanalyzer.js +132 -0
  29. package/dist/core/NodeFactory.d.ts +225 -17
  30. package/dist/core/NodeFactory.d.ts.map +1 -1
  31. package/dist/core/NodeFactory.js +208 -18
  32. package/dist/core/ScopeTracker.d.ts +84 -0
  33. package/dist/core/ScopeTracker.d.ts.map +1 -0
  34. package/dist/core/ScopeTracker.js +116 -0
  35. package/dist/core/SemanticId.d.ts +90 -0
  36. package/dist/core/SemanticId.d.ts.map +1 -0
  37. package/dist/core/SemanticId.js +115 -0
  38. package/dist/core/VersionManager.d.ts.map +1 -1
  39. package/dist/core/VersionManager.js +3 -2
  40. package/dist/core/nodes/ArgumentExpressionNode.d.ts +43 -0
  41. package/dist/core/nodes/ArgumentExpressionNode.d.ts.map +1 -0
  42. package/dist/core/nodes/ArgumentExpressionNode.js +60 -0
  43. package/dist/core/nodes/ArrayLiteralNode.d.ts +27 -0
  44. package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -0
  45. package/dist/core/nodes/ArrayLiteralNode.js +41 -0
  46. package/dist/core/nodes/CallSiteNode.d.ts +28 -0
  47. package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
  48. package/dist/core/nodes/CallSiteNode.js +46 -0
  49. package/dist/core/nodes/ClassNode.d.ts +33 -1
  50. package/dist/core/nodes/ClassNode.d.ts.map +1 -1
  51. package/dist/core/nodes/ClassNode.js +46 -2
  52. package/dist/core/nodes/DecoratorNode.d.ts +42 -0
  53. package/dist/core/nodes/DecoratorNode.d.ts.map +1 -0
  54. package/dist/core/nodes/DecoratorNode.js +62 -0
  55. package/dist/core/nodes/EnumNode.d.ts +42 -0
  56. package/dist/core/nodes/EnumNode.d.ts.map +1 -0
  57. package/dist/core/nodes/EnumNode.js +54 -0
  58. package/dist/core/nodes/ExportNode.d.ts +37 -1
  59. package/dist/core/nodes/ExportNode.d.ts.map +1 -1
  60. package/dist/core/nodes/ExportNode.js +48 -2
  61. package/dist/core/nodes/ExpressionNode.d.ts +97 -0
  62. package/dist/core/nodes/ExpressionNode.d.ts.map +1 -0
  63. package/dist/core/nodes/ExpressionNode.js +178 -0
  64. package/dist/core/nodes/ExternalModuleNode.d.ts +28 -0
  65. package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
  66. package/dist/core/nodes/ExternalModuleNode.js +41 -0
  67. package/dist/core/nodes/ExternalStdioNode.d.ts +13 -6
  68. package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -1
  69. package/dist/core/nodes/ExternalStdioNode.js +15 -8
  70. package/dist/core/nodes/FunctionNode.d.ts +36 -0
  71. package/dist/core/nodes/FunctionNode.d.ts.map +1 -1
  72. package/dist/core/nodes/FunctionNode.js +80 -1
  73. package/dist/core/nodes/ImportNode.d.ts +19 -5
  74. package/dist/core/nodes/ImportNode.d.ts.map +1 -1
  75. package/dist/core/nodes/ImportNode.js +23 -5
  76. package/dist/core/nodes/InterfaceNode.d.ts +46 -0
  77. package/dist/core/nodes/InterfaceNode.d.ts.map +1 -0
  78. package/dist/core/nodes/InterfaceNode.js +55 -0
  79. package/dist/core/nodes/IssueNode.d.ts +73 -0
  80. package/dist/core/nodes/IssueNode.d.ts.map +1 -0
  81. package/dist/core/nodes/IssueNode.js +129 -0
  82. package/dist/core/nodes/MethodCallNode.d.ts +30 -0
  83. package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
  84. package/dist/core/nodes/MethodCallNode.js +49 -0
  85. package/dist/core/nodes/MethodNode.d.ts +32 -0
  86. package/dist/core/nodes/MethodNode.d.ts.map +1 -1
  87. package/dist/core/nodes/MethodNode.js +48 -0
  88. package/dist/core/nodes/ModuleNode.d.ts +31 -0
  89. package/dist/core/nodes/ModuleNode.d.ts.map +1 -1
  90. package/dist/core/nodes/ModuleNode.js +37 -0
  91. package/dist/core/nodes/NetworkRequestNode.d.ts +54 -0
  92. package/dist/core/nodes/NetworkRequestNode.d.ts.map +1 -0
  93. package/dist/core/nodes/NetworkRequestNode.js +65 -0
  94. package/dist/core/nodes/ObjectLiteralNode.d.ts +27 -0
  95. package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -0
  96. package/dist/core/nodes/ObjectLiteralNode.js +41 -0
  97. package/dist/core/nodes/ScopeNode.d.ts +31 -0
  98. package/dist/core/nodes/ScopeNode.d.ts.map +1 -1
  99. package/dist/core/nodes/ScopeNode.js +49 -0
  100. package/dist/core/nodes/TypeNode.d.ts +36 -0
  101. package/dist/core/nodes/TypeNode.d.ts.map +1 -0
  102. package/dist/core/nodes/TypeNode.js +53 -0
  103. package/dist/core/nodes/VariableDeclarationNode.d.ts +27 -0
  104. package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
  105. package/dist/core/nodes/VariableDeclarationNode.js +40 -0
  106. package/dist/core/nodes/index.d.ts +12 -1
  107. package/dist/core/nodes/index.d.ts.map +1 -1
  108. package/dist/core/nodes/index.js +14 -0
  109. package/dist/diagnostics/DiagnosticCollector.d.ts +98 -0
  110. package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
  111. package/dist/diagnostics/DiagnosticCollector.js +129 -0
  112. package/dist/diagnostics/DiagnosticReporter.d.ts +77 -0
  113. package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
  114. package/dist/diagnostics/DiagnosticReporter.js +159 -0
  115. package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
  116. package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
  117. package/dist/diagnostics/DiagnosticWriter.js +43 -0
  118. package/dist/diagnostics/index.d.ts +14 -0
  119. package/dist/diagnostics/index.d.ts.map +1 -0
  120. package/dist/diagnostics/index.js +11 -0
  121. package/dist/errors/GrafemaError.d.ts +118 -0
  122. package/dist/errors/GrafemaError.d.ts.map +1 -0
  123. package/dist/errors/GrafemaError.js +131 -0
  124. package/dist/index.d.ts +57 -1
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +54 -1
  127. package/dist/logging/Logger.d.ts +48 -0
  128. package/dist/logging/Logger.d.ts.map +1 -0
  129. package/dist/logging/Logger.js +134 -0
  130. package/dist/plugins/Plugin.d.ts +5 -1
  131. package/dist/plugins/Plugin.d.ts.map +1 -1
  132. package/dist/plugins/Plugin.js +33 -0
  133. package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
  134. package/dist/plugins/analysis/DatabaseAnalyzer.js +13 -6
  135. package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
  136. package/dist/plugins/analysis/ExpressAnalyzer.js +27 -19
  137. package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
  138. package/dist/plugins/analysis/ExpressRouteAnalyzer.js +21 -14
  139. package/dist/plugins/analysis/FetchAnalyzer.d.ts +1 -0
  140. package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
  141. package/dist/plugins/analysis/FetchAnalyzer.js +34 -14
  142. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +6 -3
  143. package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
  144. package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +76 -80
  145. package/dist/plugins/analysis/JSASTAnalyzer.d.ts +180 -17
  146. package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
  147. package/dist/plugins/analysis/JSASTAnalyzer.js +1171 -471
  148. package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
  149. package/dist/plugins/analysis/ReactAnalyzer.js +56 -57
  150. package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
  151. package/dist/plugins/analysis/RustAnalyzer.js +15 -10
  152. package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
  153. package/dist/plugins/analysis/SQLiteAnalyzer.js +9 -7
  154. package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
  155. package/dist/plugins/analysis/ServiceLayerAnalyzer.js +21 -9
  156. package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
  157. package/dist/plugins/analysis/SocketIOAnalyzer.js +27 -15
  158. package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
  159. package/dist/plugins/analysis/SystemDbAnalyzer.js +15 -5
  160. package/dist/plugins/analysis/ast/GraphBuilder.d.ts +34 -4
  161. package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
  162. package/dist/plugins/analysis/ast/GraphBuilder.js +318 -298
  163. package/dist/plugins/analysis/ast/IdGenerator.d.ts +105 -0
  164. package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -0
  165. package/dist/plugins/analysis/ast/IdGenerator.js +116 -0
  166. package/dist/plugins/analysis/ast/types.d.ts +176 -5
  167. package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
  168. package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +33 -0
  169. package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -0
  170. package/dist/plugins/analysis/ast/utils/createParameterNodes.js +89 -0
  171. package/dist/plugins/analysis/ast/utils/index.d.ts +6 -0
  172. package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -0
  173. package/dist/plugins/analysis/ast/utils/index.js +5 -0
  174. package/dist/plugins/analysis/ast/utils/location.d.ts +87 -0
  175. package/dist/plugins/analysis/ast/utils/location.d.ts.map +1 -0
  176. package/dist/plugins/analysis/ast/utils/location.js +78 -0
  177. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +9 -4
  178. package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
  179. package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +6 -5
  180. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +99 -9
  181. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
  182. package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +663 -125
  183. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +4 -1
  184. package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
  185. package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +72 -32
  186. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +4 -1
  187. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
  188. package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +128 -63
  189. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
  190. package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +11 -8
  191. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +12 -1
  192. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
  193. package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +36 -14
  194. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +4 -1
  195. package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
  196. package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +17 -13
  197. package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
  198. package/dist/plugins/discovery/MonorepoServiceDiscovery.js +3 -2
  199. package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
  200. package/dist/plugins/discovery/SimpleProjectDiscovery.js +5 -1
  201. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts +22 -0
  202. package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -0
  203. package/dist/plugins/discovery/WorkspaceDiscovery.js +136 -0
  204. package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts +46 -0
  205. package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts.map +1 -0
  206. package/dist/plugins/discovery/resolveSourceEntrypoint.js +86 -0
  207. package/dist/plugins/discovery/workspaces/detector.d.ts +21 -0
  208. package/dist/plugins/discovery/workspaces/detector.d.ts.map +1 -0
  209. package/dist/plugins/discovery/workspaces/detector.js +49 -0
  210. package/dist/plugins/discovery/workspaces/globResolver.d.ts +35 -0
  211. package/dist/plugins/discovery/workspaces/globResolver.d.ts.map +1 -0
  212. package/dist/plugins/discovery/workspaces/globResolver.js +184 -0
  213. package/dist/plugins/discovery/workspaces/index.d.ts +9 -0
  214. package/dist/plugins/discovery/workspaces/index.d.ts.map +1 -0
  215. package/dist/plugins/discovery/workspaces/index.js +8 -0
  216. package/dist/plugins/discovery/workspaces/parsers.d.ts +38 -0
  217. package/dist/plugins/discovery/workspaces/parsers.d.ts.map +1 -0
  218. package/dist/plugins/discovery/workspaces/parsers.js +80 -0
  219. package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
  220. package/dist/plugins/enrichment/AliasTracker.js +14 -8
  221. package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
  222. package/dist/plugins/enrichment/HTTPConnectionEnricher.js +14 -7
  223. package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
  224. package/dist/plugins/enrichment/ImportExportLinker.js +23 -6
  225. package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
  226. package/dist/plugins/enrichment/MethodCallResolver.js +18 -12
  227. package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
  228. package/dist/plugins/enrichment/MountPointResolver.js +8 -3
  229. package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
  230. package/dist/plugins/enrichment/PrefixEvaluator.js +16 -7
  231. package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
  232. package/dist/plugins/enrichment/RustFFIEnricher.js +6 -5
  233. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +17 -0
  234. package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
  235. package/dist/plugins/enrichment/ValueDomainAnalyzer.js +129 -10
  236. package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
  237. package/dist/plugins/indexing/IncrementalModuleIndexer.js +23 -14
  238. package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
  239. package/dist/plugins/indexing/JSModuleIndexer.js +63 -31
  240. package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
  241. package/dist/plugins/indexing/RustModuleIndexer.js +5 -4
  242. package/dist/plugins/indexing/ServiceDetector.d.ts +10 -0
  243. package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -1
  244. package/dist/plugins/indexing/ServiceDetector.js +28 -15
  245. package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
  246. package/dist/plugins/validation/CallResolverValidator.js +8 -7
  247. package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
  248. package/dist/plugins/validation/DataFlowValidator.js +17 -12
  249. package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -1
  250. package/dist/plugins/validation/EvalBanValidator.js +17 -16
  251. package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
  252. package/dist/plugins/validation/GraphConnectivityValidator.js +19 -23
  253. package/dist/plugins/validation/NodeCreationValidator.d.ts +85 -0
  254. package/dist/plugins/validation/NodeCreationValidator.d.ts.map +1 -0
  255. package/dist/plugins/validation/NodeCreationValidator.js +415 -0
  256. package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
  257. package/dist/plugins/validation/SQLInjectionValidator.js +59 -16
  258. package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -1
  259. package/dist/plugins/validation/ShadowingDetector.js +6 -5
  260. package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
  261. package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +12 -11
  262. package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
  263. package/dist/plugins/vcs/GitPlugin.js +10 -12
  264. package/dist/plugins/vcs/VCSPlugin.d.ts +3 -2
  265. package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -1
  266. package/dist/plugins/vcs/VCSPlugin.js +5 -5
  267. package/dist/storage/backends/RFDBServerBackend.d.ts +10 -17
  268. package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
  269. package/dist/storage/backends/RFDBServerBackend.js +31 -10
  270. package/dist/validation/PathValidator.d.ts +1 -2
  271. package/dist/validation/PathValidator.d.ts.map +1 -1
  272. package/package.json +3 -3
  273. package/src/Orchestrator.ts +237 -24
  274. package/src/config/ConfigLoader.ts +263 -0
  275. package/src/config/index.ts +5 -0
  276. package/src/core/ASTWorker.ts +143 -139
  277. package/src/core/CoverageAnalyzer.ts +243 -0
  278. package/src/core/FileNodeManager.ts +100 -0
  279. package/src/core/GraphFreshnessChecker.ts +143 -0
  280. package/src/core/HashUtils.ts +48 -0
  281. package/src/core/IncrementalReanalyzer.ts +192 -0
  282. package/src/core/NodeFactory.ts +401 -18
  283. package/src/core/ScopeTracker.ts +154 -0
  284. package/src/core/SemanticId.ts +192 -0
  285. package/src/core/VersionManager.ts +3 -2
  286. package/src/core/nodes/ArgumentExpressionNode.ts +89 -0
  287. package/src/core/nodes/ArrayLiteralNode.ts +65 -0
  288. package/src/core/nodes/CallSiteNode.ts +58 -0
  289. package/src/core/nodes/ClassNode.ts +63 -2
  290. package/src/core/nodes/DecoratorNode.ts +91 -0
  291. package/src/core/nodes/EnumNode.ts +86 -0
  292. package/src/core/nodes/ExportNode.ts +70 -2
  293. package/src/core/nodes/ExpressionNode.ts +231 -0
  294. package/src/core/nodes/ExternalModuleNode.ts +56 -0
  295. package/src/core/nodes/ExternalStdioNode.ts +17 -9
  296. package/src/core/nodes/FunctionNode.ts +101 -1
  297. package/src/core/nodes/ImportNode.ts +32 -10
  298. package/src/core/nodes/InterfaceNode.ts +91 -0
  299. package/src/core/nodes/IssueNode.ts +177 -0
  300. package/src/core/nodes/MethodCallNode.ts +64 -0
  301. package/src/core/nodes/MethodNode.ts +63 -0
  302. package/src/core/nodes/ModuleNode.ts +50 -0
  303. package/src/core/nodes/NetworkRequestNode.ts +77 -0
  304. package/src/core/nodes/ObjectLiteralNode.ts +65 -0
  305. package/src/core/nodes/ScopeNode.ts +65 -0
  306. package/src/core/nodes/TypeNode.ts +78 -0
  307. package/src/core/nodes/VariableDeclarationNode.ts +52 -0
  308. package/src/core/nodes/index.ts +18 -1
  309. package/src/diagnostics/DiagnosticCollector.ts +163 -0
  310. package/src/diagnostics/DiagnosticReporter.ts +204 -0
  311. package/src/diagnostics/DiagnosticWriter.ts +50 -0
  312. package/src/diagnostics/index.ts +16 -0
  313. package/src/errors/GrafemaError.ts +174 -0
  314. package/src/index.ts +148 -1
  315. package/src/logging/Logger.ts +152 -0
  316. package/src/plugins/Plugin.ts +42 -0
  317. package/src/plugins/analysis/DatabaseAnalyzer.ts +14 -8
  318. package/src/plugins/analysis/ExpressAnalyzer.ts +29 -19
  319. package/src/plugins/analysis/ExpressRouteAnalyzer.ts +22 -21
  320. package/src/plugins/analysis/FetchAnalyzer.ts +39 -16
  321. package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
  322. package/src/plugins/analysis/JSASTAnalyzer.ts +1483 -503
  323. package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
  324. package/src/plugins/analysis/RustAnalyzer.ts +15 -10
  325. package/src/plugins/analysis/SQLiteAnalyzer.ts +10 -7
  326. package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
  327. package/src/plugins/analysis/SocketIOAnalyzer.ts +31 -22
  328. package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
  329. package/src/plugins/analysis/ast/GraphBuilder.ts +439 -327
  330. package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
  331. package/src/plugins/analysis/ast/types.ts +209 -6
  332. package/src/plugins/analysis/ast/utils/createParameterNodes.ts +104 -0
  333. package/src/plugins/analysis/ast/utils/index.ts +12 -0
  334. package/src/plugins/analysis/ast/utils/location.ts +103 -0
  335. package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +11 -8
  336. package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +909 -83
  337. package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
  338. package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +159 -93
  339. package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +12 -8
  340. package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
  341. package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +37 -17
  342. package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
  343. package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
  344. package/src/plugins/discovery/WorkspaceDiscovery.ts +177 -0
  345. package/src/plugins/discovery/resolveSourceEntrypoint.ts +103 -0
  346. package/src/plugins/discovery/workspaces/detector.ts +63 -0
  347. package/src/plugins/discovery/workspaces/globResolver.ts +229 -0
  348. package/src/plugins/discovery/workspaces/index.ts +23 -0
  349. package/src/plugins/discovery/workspaces/parsers.ts +99 -0
  350. package/src/plugins/enrichment/AliasTracker.ts +14 -8
  351. package/src/plugins/enrichment/HTTPConnectionEnricher.ts +14 -7
  352. package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
  353. package/src/plugins/enrichment/MethodCallResolver.ts +18 -12
  354. package/src/plugins/enrichment/MountPointResolver.ts +8 -3
  355. package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
  356. package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
  357. package/src/plugins/enrichment/ValueDomainAnalyzer.ts +149 -12
  358. package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
  359. package/src/plugins/indexing/JSModuleIndexer.ts +74 -34
  360. package/src/plugins/indexing/RustModuleIndexer.ts +5 -4
  361. package/src/plugins/validation/CallResolverValidator.ts +8 -7
  362. package/src/plugins/validation/DataFlowValidator.ts +16 -12
  363. package/src/plugins/validation/EvalBanValidator.ts +17 -16
  364. package/src/plugins/validation/GraphConnectivityValidator.ts +19 -23
  365. package/src/plugins/validation/NodeCreationValidator.ts +554 -0
  366. package/src/plugins/validation/SQLInjectionValidator.ts +61 -15
  367. package/src/plugins/validation/ShadowingDetector.ts +6 -5
  368. package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +12 -11
  369. package/src/plugins/vcs/GitPlugin.ts +40 -12
  370. package/src/plugins/vcs/VCSPlugin.ts +7 -5
  371. package/src/storage/backends/RFDBServerBackend.ts +43 -29
  372. package/src/validation/PathValidator.ts +1 -1
  373. package/dist/core/AnalysisWorker.d.ts +0 -14
  374. package/dist/core/AnalysisWorker.d.ts.map +0 -1
  375. package/dist/core/AnalysisWorker.js +0 -307
  376. package/dist/core/ParallelAnalyzer.d.ts +0 -120
  377. package/dist/core/ParallelAnalyzer.d.ts.map +0 -1
  378. package/dist/core/ParallelAnalyzer.js +0 -331
  379. package/dist/core/QueueWorker.d.ts +0 -12
  380. package/dist/core/QueueWorker.d.ts.map +0 -1
  381. package/dist/core/QueueWorker.js +0 -567
  382. package/dist/core/RFDBClient.d.ts +0 -179
  383. package/dist/core/RFDBClient.d.ts.map +0 -1
  384. package/dist/core/RFDBClient.js +0 -429
  385. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +0 -19
  386. package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +0 -1
  387. package/dist/plugins/discovery/ZonServiceDiscovery.js +0 -204
  388. package/src/core/AnalysisWorker.ts +0 -410
  389. package/src/core/ParallelAnalyzer.ts +0 -476
  390. package/src/core/QueueWorker.ts +0 -780
  391. package/src/plugins/indexing/ServiceDetector.ts +0 -230
@@ -9,9 +9,22 @@
9
9
  */
10
10
  import { ASTVisitor } from './ASTVisitor.js';
11
11
  import { ExpressionEvaluator } from '../ExpressionEvaluator.js';
12
+ import { computeSemanticId } from '../../../../core/SemanticId.js';
13
+ import { IdGenerator } from '../IdGenerator.js';
14
+ import { NodeFactory } from '../../../../core/NodeFactory.js';
15
+ import { ObjectLiteralNode } from '../../../../core/nodes/ObjectLiteralNode.js';
16
+ import { ArrayLiteralNode } from '../../../../core/nodes/ArrayLiteralNode.js';
17
+ import { getLine, getColumn } from '../utils/location.js';
12
18
  export class CallExpressionVisitor extends ASTVisitor {
13
- constructor(module, collections) {
19
+ scopeTracker;
20
+ /**
21
+ * @param module - Current module being analyzed
22
+ * @param collections - Must contain arrays and counter refs
23
+ * @param scopeTracker - Optional ScopeTracker for semantic ID generation
24
+ */
25
+ constructor(module, collections, scopeTracker) {
14
26
  super(module, collections);
27
+ this.scopeTracker = scopeTracker;
15
28
  }
16
29
  /**
17
30
  * Extract argument information for PASSES_ARGUMENT edges
@@ -31,104 +44,157 @@ export class CallExpressionVisitor extends ASTVisitor {
31
44
  argInfo.isSpread = true;
32
45
  actualArg = arg.argument; // Get the actual argument
33
46
  }
34
- // Literal value
35
- const literalValue = ExpressionEvaluator.extractLiteralValue(actualArg);
36
- if (literalValue !== null) {
37
- const literalId = `LITERAL#arg${index}#${module.file}#${argInfo.line}:${argInfo.column}:${literalCounterRef.value++}`;
38
- literals.push({
39
- id: literalId,
40
- type: 'LITERAL',
41
- value: literalValue,
42
- valueType: typeof literalValue,
43
- file: module.file,
44
- line: argInfo.line,
45
- column: argInfo.column,
46
- parentCallId: callId,
47
- argIndex: index
48
- });
49
- argInfo.targetType = 'LITERAL';
50
- argInfo.targetId = literalId;
51
- argInfo.literalValue = literalValue;
52
- }
53
- // Variable reference
54
- else if (actualArg.type === 'Identifier') {
55
- argInfo.targetType = 'VARIABLE';
56
- argInfo.targetName = actualArg.name; // Will be resolved in GraphBuilder
57
- }
58
- // Function expression (callback)
59
- else if (actualArg.type === 'ArrowFunctionExpression' || actualArg.type === 'FunctionExpression') {
60
- argInfo.targetType = 'FUNCTION';
61
- argInfo.functionLine = actualArg.loc?.start.line;
62
- argInfo.functionColumn = actualArg.loc?.start.column;
63
- }
64
- // Call expression (nested call)
65
- else if (actualArg.type === 'CallExpression') {
66
- argInfo.targetType = 'CALL';
67
- // Nested calls will be processed separately, link by position
68
- argInfo.nestedCallLine = actualArg.loc?.start.line;
69
- argInfo.nestedCallColumn = actualArg.loc?.start.column;
70
- }
71
- // Member expression: obj.prop or obj[x]
72
- else if (actualArg.type === 'MemberExpression') {
73
- const memberExpr = actualArg;
74
- argInfo.targetType = 'EXPRESSION';
75
- argInfo.expressionType = 'MemberExpression';
76
- if (memberExpr.object.type === 'Identifier') {
77
- argInfo.objectName = memberExpr.object.name;
78
- }
79
- if (!memberExpr.computed && memberExpr.property.type === 'Identifier') {
80
- argInfo.propertyName = memberExpr.property.name;
81
- }
82
- }
83
- // Binary/Logical expression: a + b, a && b
84
- else if (actualArg.type === 'BinaryExpression' || actualArg.type === 'LogicalExpression') {
85
- const expr = actualArg;
86
- const operator = expr.operator || '?';
87
- const exprName = `<${actualArg.type}:${operator}>`;
88
- const expressionId = `EXPRESSION#${exprName}#${module.file}#${argInfo.line}:${argInfo.column}:${literalCounterRef.value++}`;
89
- // Create EXPRESSION node
90
- literals.push({
91
- id: expressionId,
92
- type: 'EXPRESSION',
93
- expressionType: actualArg.type,
94
- operator: operator,
95
- name: exprName,
96
- file: module.file,
97
- line: argInfo.line,
98
- column: argInfo.column,
47
+ // Object literal - check BEFORE extractLiteralValue to handle object-typed args properly
48
+ if (actualArg.type === 'ObjectExpression') {
49
+ const objectExpr = actualArg;
50
+ // Initialize collections if not exist (must assign back to this.collections!)
51
+ if (!this.collections.objectLiteralCounterRef) {
52
+ this.collections.objectLiteralCounterRef = { value: 0 };
53
+ }
54
+ if (!this.collections.objectLiterals) {
55
+ this.collections.objectLiterals = [];
56
+ }
57
+ if (!this.collections.objectProperties) {
58
+ this.collections.objectProperties = [];
59
+ }
60
+ const objectLiteralCounterRef = this.collections.objectLiteralCounterRef;
61
+ // Use factory to create OBJECT_LITERAL node
62
+ const objectNode = ObjectLiteralNode.create(module.file, argInfo.line, argInfo.column, {
99
63
  parentCallId: callId,
100
- argIndex: index
64
+ argIndex: index,
65
+ counter: objectLiteralCounterRef.value++
101
66
  });
102
- argInfo.targetType = 'EXPRESSION';
103
- argInfo.targetId = expressionId;
104
- argInfo.expressionType = actualArg.type;
105
- // Track DERIVES_FROM edges for identifiers in expression
106
- const identifiers = this.extractIdentifiers(actualArg);
107
- const { variableAssignments } = this.collections;
108
- if (variableAssignments) {
109
- for (const identName of identifiers) {
110
- variableAssignments.push({
111
- variableId: expressionId,
112
- sourceId: null,
113
- sourceName: identName,
114
- sourceType: 'DERIVES_FROM_VARIABLE',
115
- file: module.file
116
- });
117
- }
118
- }
119
- }
120
- // Object literal
121
- else if (actualArg.type === 'ObjectExpression') {
67
+ // Factory guarantees line is set, cast to ObjectLiteralInfo
68
+ this.collections.objectLiterals.push(objectNode);
69
+ const objectId = objectNode.id;
70
+ // Extract properties
71
+ this.extractObjectProperties(objectExpr, objectId, module, this.collections.objectProperties, this.collections.objectLiterals, objectLiteralCounterRef, literals, literalCounterRef);
122
72
  argInfo.targetType = 'OBJECT_LITERAL';
73
+ argInfo.targetId = objectId;
123
74
  }
124
- // Array literal
75
+ // Array literal - check BEFORE extractLiteralValue to handle array-typed args properly
125
76
  else if (actualArg.type === 'ArrayExpression') {
77
+ const arrayExpr = actualArg;
78
+ // Initialize collections if not exist (must assign back to this.collections!)
79
+ if (!this.collections.arrayLiteralCounterRef) {
80
+ this.collections.arrayLiteralCounterRef = { value: 0 };
81
+ }
82
+ if (!this.collections.arrayLiterals) {
83
+ this.collections.arrayLiterals = [];
84
+ }
85
+ if (!this.collections.arrayElements) {
86
+ this.collections.arrayElements = [];
87
+ }
88
+ if (!this.collections.objectLiteralCounterRef) {
89
+ this.collections.objectLiteralCounterRef = { value: 0 };
90
+ }
91
+ if (!this.collections.objectLiterals) {
92
+ this.collections.objectLiterals = [];
93
+ }
94
+ if (!this.collections.objectProperties) {
95
+ this.collections.objectProperties = [];
96
+ }
97
+ const arrayLiteralCounterRef = this.collections.arrayLiteralCounterRef;
98
+ // Use factory to create ARRAY_LITERAL node
99
+ const arrayNode = ArrayLiteralNode.create(module.file, argInfo.line, argInfo.column, {
100
+ parentCallId: callId,
101
+ argIndex: index,
102
+ counter: arrayLiteralCounterRef.value++
103
+ });
104
+ // Factory guarantees line is set, cast to ArrayLiteralInfo
105
+ this.collections.arrayLiterals.push(arrayNode);
106
+ const arrayId = arrayNode.id;
107
+ // Extract elements
108
+ this.extractArrayElements(arrayExpr, arrayId, module, this.collections.arrayElements, this.collections.arrayLiterals, arrayLiteralCounterRef, this.collections.objectLiterals, this.collections.objectLiteralCounterRef, this.collections.objectProperties, literals, literalCounterRef);
126
109
  argInfo.targetType = 'ARRAY_LITERAL';
110
+ argInfo.targetId = arrayId;
127
111
  }
128
- // Other expression types
112
+ // Literal value (primitives only - objects/arrays handled above)
129
113
  else {
130
- argInfo.targetType = 'EXPRESSION';
131
- argInfo.expressionType = actualArg.type;
114
+ const literalValue = ExpressionEvaluator.extractLiteralValue(actualArg);
115
+ if (literalValue !== null) {
116
+ const literalId = `LITERAL#arg${index}#${module.file}#${argInfo.line}:${argInfo.column}:${literalCounterRef.value++}`;
117
+ literals.push({
118
+ id: literalId,
119
+ type: 'LITERAL',
120
+ value: literalValue,
121
+ valueType: typeof literalValue,
122
+ file: module.file,
123
+ line: argInfo.line,
124
+ column: argInfo.column,
125
+ parentCallId: callId,
126
+ argIndex: index
127
+ });
128
+ argInfo.targetType = 'LITERAL';
129
+ argInfo.targetId = literalId;
130
+ argInfo.literalValue = literalValue;
131
+ }
132
+ // Variable reference
133
+ else if (actualArg.type === 'Identifier') {
134
+ argInfo.targetType = 'VARIABLE';
135
+ argInfo.targetName = actualArg.name; // Will be resolved in GraphBuilder
136
+ }
137
+ // Function expression (callback)
138
+ else if (actualArg.type === 'ArrowFunctionExpression' || actualArg.type === 'FunctionExpression') {
139
+ argInfo.targetType = 'FUNCTION';
140
+ argInfo.functionLine = actualArg.loc?.start.line;
141
+ argInfo.functionColumn = actualArg.loc?.start.column;
142
+ }
143
+ // Call expression (nested call)
144
+ else if (actualArg.type === 'CallExpression') {
145
+ argInfo.targetType = 'CALL';
146
+ // Nested calls will be processed separately, link by position
147
+ argInfo.nestedCallLine = actualArg.loc?.start.line;
148
+ argInfo.nestedCallColumn = actualArg.loc?.start.column;
149
+ }
150
+ // Member expression: obj.prop or obj[x]
151
+ else if (actualArg.type === 'MemberExpression') {
152
+ const memberExpr = actualArg;
153
+ argInfo.targetType = 'EXPRESSION';
154
+ argInfo.expressionType = 'MemberExpression';
155
+ if (memberExpr.object.type === 'Identifier') {
156
+ argInfo.objectName = memberExpr.object.name;
157
+ }
158
+ if (!memberExpr.computed && memberExpr.property.type === 'Identifier') {
159
+ argInfo.propertyName = memberExpr.property.name;
160
+ }
161
+ }
162
+ // Binary/Logical expression: a + b, a && b
163
+ else if (actualArg.type === 'BinaryExpression' || actualArg.type === 'LogicalExpression') {
164
+ const expr = actualArg;
165
+ const operator = expr.operator || '?';
166
+ const counter = literalCounterRef.value++;
167
+ // Create EXPRESSION node via NodeFactory
168
+ const expressionNode = NodeFactory.createArgumentExpression(actualArg.type, module.file, argInfo.line, argInfo.column, {
169
+ parentCallId: callId,
170
+ argIndex: index,
171
+ operator,
172
+ counter
173
+ });
174
+ literals.push(expressionNode);
175
+ argInfo.targetType = 'EXPRESSION';
176
+ argInfo.targetId = expressionNode.id;
177
+ argInfo.expressionType = actualArg.type;
178
+ // Track DERIVES_FROM edges for identifiers in expression
179
+ const identifiers = this.extractIdentifiers(actualArg);
180
+ const { variableAssignments } = this.collections;
181
+ if (variableAssignments) {
182
+ for (const identName of identifiers) {
183
+ variableAssignments.push({
184
+ variableId: expressionNode.id,
185
+ sourceId: null,
186
+ sourceName: identName,
187
+ sourceType: 'DERIVES_FROM_VARIABLE',
188
+ file: module.file
189
+ });
190
+ }
191
+ }
192
+ }
193
+ // Other expression types (fallback for unhandled expression types)
194
+ else {
195
+ argInfo.targetType = 'EXPRESSION';
196
+ argInfo.expressionType = actualArg.type;
197
+ }
132
198
  }
133
199
  callArguments.push(argInfo);
134
200
  });
@@ -186,28 +252,435 @@ export class CallExpressionVisitor extends ASTVisitor {
186
252
  return Array.from(identifiers);
187
253
  }
188
254
  /**
189
- * Get a stable scope ID for a function parent
190
- * Format must match what FunctionVisitor creates:
191
- * - FunctionDeclaration: FUNCTION#name#file#line
192
- * - ArrowFunctionExpression: FUNCTION#name#file#line:col:counter
255
+ * Extract object properties and create ObjectPropertyInfo records
256
+ */
257
+ extractObjectProperties(objectExpr, objectId, module, objectProperties, objectLiterals, objectLiteralCounterRef, literals, literalCounterRef) {
258
+ for (const prop of objectExpr.properties) {
259
+ const propLine = prop.loc?.start.line || 0;
260
+ const propColumn = prop.loc?.start.column || 0;
261
+ // Handle spread properties: { ...other }
262
+ if (prop.type === 'SpreadElement') {
263
+ const spreadArg = prop.argument;
264
+ const propertyInfo = {
265
+ objectId,
266
+ propertyName: '<spread>',
267
+ valueType: 'SPREAD',
268
+ file: module.file,
269
+ line: propLine,
270
+ column: propColumn
271
+ };
272
+ if (spreadArg.type === 'Identifier') {
273
+ propertyInfo.valueName = spreadArg.name;
274
+ propertyInfo.valueType = 'VARIABLE';
275
+ }
276
+ objectProperties.push(propertyInfo);
277
+ continue;
278
+ }
279
+ // Handle regular properties
280
+ if (prop.type === 'ObjectProperty') {
281
+ const objProp = prop;
282
+ let propertyName;
283
+ // Get property name
284
+ if (objProp.key.type === 'Identifier') {
285
+ propertyName = objProp.key.name;
286
+ }
287
+ else if (objProp.key.type === 'StringLiteral') {
288
+ propertyName = objProp.key.value;
289
+ }
290
+ else if (objProp.key.type === 'NumericLiteral') {
291
+ propertyName = String(objProp.key.value);
292
+ }
293
+ else {
294
+ propertyName = '<computed>';
295
+ }
296
+ const propertyInfo = {
297
+ objectId,
298
+ propertyName,
299
+ file: module.file,
300
+ line: propLine,
301
+ column: propColumn,
302
+ valueType: 'EXPRESSION'
303
+ };
304
+ const value = objProp.value;
305
+ // Nested object literal - check BEFORE extractLiteralValue
306
+ if (value.type === 'ObjectExpression') {
307
+ // Use factory - do NOT pass argIndex for nested literals (uses 'obj' suffix)
308
+ const nestedObjectNode = ObjectLiteralNode.create(module.file, value.loc?.start.line || 0, value.loc?.start.column || 0, {
309
+ counter: objectLiteralCounterRef.value++
310
+ });
311
+ objectLiterals.push(nestedObjectNode);
312
+ const nestedObjectId = nestedObjectNode.id;
313
+ // Recursively extract nested properties
314
+ this.extractObjectProperties(value, nestedObjectId, module, objectProperties, objectLiterals, objectLiteralCounterRef, literals, literalCounterRef);
315
+ propertyInfo.valueType = 'OBJECT_LITERAL';
316
+ propertyInfo.nestedObjectId = nestedObjectId;
317
+ propertyInfo.valueNodeId = nestedObjectId;
318
+ }
319
+ // Nested array literal - check BEFORE extractLiteralValue
320
+ else if (value.type === 'ArrayExpression') {
321
+ const arrayLiteralCounterRef = (this.collections.arrayLiteralCounterRef ?? { value: 0 });
322
+ const arrayLiterals = this.collections.arrayLiterals ?? [];
323
+ const arrayElements = this.collections.arrayElements ?? [];
324
+ // Use factory - do NOT pass argIndex for nested literals (uses 'arr' suffix)
325
+ const nestedArrayNode = ArrayLiteralNode.create(module.file, value.loc?.start.line || 0, value.loc?.start.column || 0, {
326
+ counter: arrayLiteralCounterRef.value++
327
+ });
328
+ arrayLiterals.push(nestedArrayNode);
329
+ const nestedArrayId = nestedArrayNode.id;
330
+ // Recursively extract array elements
331
+ this.extractArrayElements(value, nestedArrayId, module, arrayElements, arrayLiterals, arrayLiteralCounterRef, objectLiterals, objectLiteralCounterRef, objectProperties, literals, literalCounterRef);
332
+ propertyInfo.valueType = 'ARRAY_LITERAL';
333
+ propertyInfo.nestedArrayId = nestedArrayId;
334
+ propertyInfo.valueNodeId = nestedArrayId;
335
+ }
336
+ // Literal value (primitives only - objects/arrays handled above)
337
+ else {
338
+ const literalValue = ExpressionEvaluator.extractLiteralValue(value);
339
+ if (literalValue !== null) {
340
+ const literalId = `LITERAL#${propertyName}#${module.file}#${propLine}:${propColumn}:${literalCounterRef.value++}`;
341
+ literals.push({
342
+ id: literalId,
343
+ type: 'LITERAL',
344
+ value: literalValue,
345
+ valueType: typeof literalValue,
346
+ file: module.file,
347
+ line: propLine,
348
+ column: propColumn,
349
+ parentCallId: objectId,
350
+ argIndex: 0
351
+ });
352
+ propertyInfo.valueType = 'LITERAL';
353
+ propertyInfo.valueNodeId = literalId;
354
+ propertyInfo.literalValue = literalValue;
355
+ }
356
+ // Variable reference
357
+ else if (value.type === 'Identifier') {
358
+ propertyInfo.valueType = 'VARIABLE';
359
+ propertyInfo.valueName = value.name;
360
+ }
361
+ // Call expression
362
+ else if (value.type === 'CallExpression') {
363
+ propertyInfo.valueType = 'CALL';
364
+ propertyInfo.callLine = value.loc?.start.line;
365
+ propertyInfo.callColumn = value.loc?.start.column;
366
+ }
367
+ // Other expressions
368
+ else {
369
+ propertyInfo.valueType = 'EXPRESSION';
370
+ }
371
+ }
372
+ objectProperties.push(propertyInfo);
373
+ }
374
+ // Handle object methods: { foo() {} }
375
+ else if (prop.type === 'ObjectMethod') {
376
+ const propertyName = prop.key.type === 'Identifier' ? prop.key.name : '<computed>';
377
+ objectProperties.push({
378
+ objectId,
379
+ propertyName,
380
+ valueType: 'EXPRESSION',
381
+ file: module.file,
382
+ line: propLine,
383
+ column: propColumn
384
+ });
385
+ }
386
+ }
387
+ }
388
+ /**
389
+ * Extract array elements and create ArrayElementInfo records
390
+ */
391
+ extractArrayElements(arrayExpr, arrayId, module, arrayElements, arrayLiterals, arrayLiteralCounterRef, objectLiterals, objectLiteralCounterRef, objectProperties, literals, literalCounterRef) {
392
+ arrayExpr.elements.forEach((element, index) => {
393
+ if (!element)
394
+ return; // Skip holes in arrays
395
+ const elemLine = element.loc?.start.line || 0;
396
+ const elemColumn = element.loc?.start.column || 0;
397
+ const elementInfo = {
398
+ arrayId,
399
+ index,
400
+ file: module.file,
401
+ line: elemLine,
402
+ column: elemColumn,
403
+ valueType: 'EXPRESSION'
404
+ };
405
+ // Handle spread elements: [...arr]
406
+ if (element.type === 'SpreadElement') {
407
+ const spreadArg = element.argument;
408
+ elementInfo.valueType = 'SPREAD';
409
+ if (spreadArg.type === 'Identifier') {
410
+ elementInfo.valueName = spreadArg.name;
411
+ }
412
+ arrayElements.push(elementInfo);
413
+ return;
414
+ }
415
+ // Nested object literal - check BEFORE extractLiteralValue
416
+ if (element.type === 'ObjectExpression') {
417
+ // Use factory - do NOT pass argIndex for nested literals (uses 'obj' suffix)
418
+ const nestedObjectNode = ObjectLiteralNode.create(module.file, elemLine, elemColumn, {
419
+ counter: objectLiteralCounterRef.value++
420
+ });
421
+ objectLiterals.push(nestedObjectNode);
422
+ const nestedObjectId = nestedObjectNode.id;
423
+ // Recursively extract properties
424
+ this.extractObjectProperties(element, nestedObjectId, module, objectProperties, objectLiterals, objectLiteralCounterRef, literals, literalCounterRef);
425
+ elementInfo.valueType = 'OBJECT_LITERAL';
426
+ elementInfo.nestedObjectId = nestedObjectId;
427
+ elementInfo.valueNodeId = nestedObjectId;
428
+ }
429
+ // Nested array literal - check BEFORE extractLiteralValue
430
+ else if (element.type === 'ArrayExpression') {
431
+ // Use factory - do NOT pass argIndex for nested literals (uses 'arr' suffix)
432
+ const nestedArrayNode = ArrayLiteralNode.create(module.file, elemLine, elemColumn, {
433
+ counter: arrayLiteralCounterRef.value++
434
+ });
435
+ arrayLiterals.push(nestedArrayNode);
436
+ const nestedArrayId = nestedArrayNode.id;
437
+ // Recursively extract elements
438
+ this.extractArrayElements(element, nestedArrayId, module, arrayElements, arrayLiterals, arrayLiteralCounterRef, objectLiterals, objectLiteralCounterRef, objectProperties, literals, literalCounterRef);
439
+ elementInfo.valueType = 'ARRAY_LITERAL';
440
+ elementInfo.nestedArrayId = nestedArrayId;
441
+ elementInfo.valueNodeId = nestedArrayId;
442
+ }
443
+ // Literal value (primitives only - objects/arrays handled above)
444
+ else {
445
+ const literalValue = ExpressionEvaluator.extractLiteralValue(element);
446
+ if (literalValue !== null) {
447
+ const literalId = `LITERAL#elem${index}#${module.file}#${elemLine}:${elemColumn}:${literalCounterRef.value++}`;
448
+ literals.push({
449
+ id: literalId,
450
+ type: 'LITERAL',
451
+ value: literalValue,
452
+ valueType: typeof literalValue,
453
+ file: module.file,
454
+ line: elemLine,
455
+ column: elemColumn,
456
+ parentCallId: arrayId,
457
+ argIndex: index
458
+ });
459
+ elementInfo.valueType = 'LITERAL';
460
+ elementInfo.valueNodeId = literalId;
461
+ elementInfo.literalValue = literalValue;
462
+ }
463
+ // Variable reference
464
+ else if (element.type === 'Identifier') {
465
+ elementInfo.valueType = 'VARIABLE';
466
+ elementInfo.valueName = element.name;
467
+ }
468
+ // Call expression
469
+ else if (element.type === 'CallExpression') {
470
+ elementInfo.valueType = 'CALL';
471
+ elementInfo.callLine = element.loc?.start.line;
472
+ elementInfo.callColumn = element.loc?.start.column;
473
+ }
474
+ // Other expressions
475
+ else {
476
+ elementInfo.valueType = 'EXPRESSION';
477
+ }
478
+ }
479
+ arrayElements.push(elementInfo);
480
+ });
481
+ }
482
+ /**
483
+ * Detect array mutation calls (push, unshift, splice) and collect mutation info
484
+ * for later FLOWS_INTO edge creation in GraphBuilder
485
+ *
486
+ * REG-117: Added isNested, baseObjectName, propertyName for nested mutations
487
+ */
488
+ detectArrayMutation(callNode, arrayName, method, module, isNested, baseObjectName, propertyName) {
489
+ // Initialize collection if not exists
490
+ if (!this.collections.arrayMutations) {
491
+ this.collections.arrayMutations = [];
492
+ }
493
+ const arrayMutations = this.collections.arrayMutations;
494
+ const mutationArgs = [];
495
+ // For splice, only arguments from index 2 onwards are insertions
496
+ // splice(start, deleteCount, item1, item2, ...)
497
+ callNode.arguments.forEach((arg, index) => {
498
+ // Skip start and deleteCount for splice
499
+ if (method === 'splice' && index < 2)
500
+ return;
501
+ const argInfo = {
502
+ argIndex: method === 'splice' ? index - 2 : index,
503
+ isSpread: arg.type === 'SpreadElement',
504
+ valueType: 'EXPRESSION' // Default
505
+ };
506
+ let actualArg = arg;
507
+ if (arg.type === 'SpreadElement') {
508
+ actualArg = arg.argument;
509
+ }
510
+ // Determine value type
511
+ const literalValue = ExpressionEvaluator.extractLiteralValue(actualArg);
512
+ if (literalValue !== null) {
513
+ argInfo.valueType = 'LITERAL';
514
+ argInfo.literalValue = literalValue;
515
+ }
516
+ else if (actualArg.type === 'Identifier') {
517
+ argInfo.valueType = 'VARIABLE';
518
+ argInfo.valueName = actualArg.name;
519
+ }
520
+ else if (actualArg.type === 'ObjectExpression') {
521
+ argInfo.valueType = 'OBJECT_LITERAL';
522
+ }
523
+ else if (actualArg.type === 'ArrayExpression') {
524
+ argInfo.valueType = 'ARRAY_LITERAL';
525
+ }
526
+ else if (actualArg.type === 'CallExpression') {
527
+ argInfo.valueType = 'CALL';
528
+ argInfo.callLine = actualArg.loc?.start.line;
529
+ argInfo.callColumn = actualArg.loc?.start.column;
530
+ }
531
+ mutationArgs.push(argInfo);
532
+ });
533
+ // Only record if there are actual insertions
534
+ if (mutationArgs.length > 0) {
535
+ const line = callNode.loc?.start.line ?? 0;
536
+ const column = callNode.loc?.start.column ?? 0;
537
+ // Generate semantic ID for array mutation if scopeTracker available
538
+ const scopeTracker = this.scopeTracker;
539
+ let mutationId;
540
+ if (scopeTracker) {
541
+ const discriminator = scopeTracker.getItemCounter(`ARRAY_MUTATION:${arrayName}.${method}`);
542
+ mutationId = computeSemanticId('ARRAY_MUTATION', `${arrayName}.${method}`, scopeTracker.getContext(), { discriminator });
543
+ }
544
+ arrayMutations.push({
545
+ id: mutationId,
546
+ arrayName,
547
+ mutationMethod: method,
548
+ file: module.file,
549
+ line,
550
+ column,
551
+ insertedValues: mutationArgs,
552
+ // REG-117: Nested mutation fields
553
+ isNested,
554
+ baseObjectName,
555
+ propertyName
556
+ });
557
+ }
558
+ }
559
+ /**
560
+ * Detect Object.assign(target, source1, source2, ...) calls
561
+ * Creates ObjectMutationInfo for FLOWS_INTO edge generation in GraphBuilder
562
+ *
563
+ * @param callNode - The call expression node
564
+ * @param module - Current module being analyzed
565
+ */
566
+ detectObjectAssign(callNode, module) {
567
+ // Need at least 2 arguments: target and at least one source
568
+ if (callNode.arguments.length < 2)
569
+ return;
570
+ // Initialize object mutations collection if not exists
571
+ if (!this.collections.objectMutations) {
572
+ this.collections.objectMutations = [];
573
+ }
574
+ const objectMutations = this.collections.objectMutations;
575
+ // First argument is target
576
+ const targetArg = callNode.arguments[0];
577
+ let targetName;
578
+ if (targetArg.type === 'Identifier') {
579
+ targetName = targetArg.name;
580
+ }
581
+ else if (targetArg.type === 'ObjectExpression') {
582
+ targetName = '<anonymous>';
583
+ }
584
+ else {
585
+ return;
586
+ }
587
+ const line = callNode.loc?.start.line ?? 0;
588
+ const column = callNode.loc?.start.column ?? 0;
589
+ for (let i = 1; i < callNode.arguments.length; i++) {
590
+ let arg = callNode.arguments[i];
591
+ let isSpread = false;
592
+ if (arg.type === 'SpreadElement') {
593
+ isSpread = true;
594
+ arg = arg.argument;
595
+ }
596
+ const valueInfo = {
597
+ valueType: 'EXPRESSION',
598
+ argIndex: i - 1,
599
+ isSpread
600
+ };
601
+ const literalValue = ExpressionEvaluator.extractLiteralValue(arg);
602
+ if (literalValue !== null) {
603
+ valueInfo.valueType = 'LITERAL';
604
+ valueInfo.literalValue = literalValue;
605
+ }
606
+ else if (arg.type === 'Identifier') {
607
+ valueInfo.valueType = 'VARIABLE';
608
+ valueInfo.valueName = arg.name;
609
+ }
610
+ else if (arg.type === 'ObjectExpression') {
611
+ valueInfo.valueType = 'OBJECT_LITERAL';
612
+ }
613
+ else if (arg.type === 'ArrayExpression') {
614
+ valueInfo.valueType = 'ARRAY_LITERAL';
615
+ }
616
+ else if (arg.type === 'CallExpression') {
617
+ valueInfo.valueType = 'CALL';
618
+ valueInfo.callLine = arg.loc?.start.line;
619
+ valueInfo.callColumn = arg.loc?.start.column;
620
+ }
621
+ let mutationId;
622
+ if (this.scopeTracker) {
623
+ const discriminator = this.scopeTracker.getItemCounter(`OBJECT_MUTATION:Object.assign:${targetName}`);
624
+ mutationId = computeSemanticId('OBJECT_MUTATION', `Object.assign:${targetName}`, this.scopeTracker.getContext(), { discriminator });
625
+ }
626
+ objectMutations.push({
627
+ id: mutationId,
628
+ objectName: targetName,
629
+ propertyName: '<assign>',
630
+ mutationType: 'assign',
631
+ file: module.file,
632
+ line,
633
+ column,
634
+ value: valueInfo
635
+ });
636
+ }
637
+ }
638
+ /**
639
+ * Get a stable scope ID for a function parent.
640
+ *
641
+ * Format must match what FunctionVisitor/ClassVisitor creates (semantic ID):
642
+ * - Module-level function: {file}->global->FUNCTION->{name}
643
+ * - Class method: {file}->{className}->FUNCTION->{methodName}
193
644
  *
194
- * NOTE: We don't have access to the counter here, so for arrow functions
195
- * we try to match by name+file+line:col. This may not always work for
196
- * multiple arrow functions on the same line.
645
+ * Reconstructs scope path by walking up the AST.
197
646
  */
198
647
  getFunctionScopeId(functionParent, module) {
199
648
  const funcNode = functionParent.node;
200
- const line = funcNode.loc?.start.line || 0;
201
- const col = funcNode.loc?.start.column || 0;
202
- // FunctionDeclaration with name
649
+ // Get function name
650
+ let funcName;
203
651
  if (funcNode.type === 'FunctionDeclaration' && funcNode.id?.name) {
204
- return `FUNCTION#${funcNode.id.name}#${module.file}#${line}`;
652
+ funcName = funcNode.id.name;
653
+ }
654
+ else if (funcNode.type === 'ClassMethod' && funcNode.key?.type === 'Identifier') {
655
+ funcName = funcNode.key.name;
656
+ }
657
+ if (!funcName) {
658
+ // Anonymous function - fall back to module scope
659
+ return module.id;
660
+ }
661
+ // Build scope path by walking up the AST
662
+ const scopePath = [];
663
+ let current = functionParent.parentPath;
664
+ while (current) {
665
+ const node = current.node;
666
+ if (node.type === 'ClassDeclaration' && node.id?.name) {
667
+ scopePath.unshift(node.id.name);
668
+ break; // Class is the outermost scope we need
669
+ }
670
+ else if (node.type === 'ClassBody') {
671
+ // Continue up to ClassDeclaration
672
+ }
673
+ else if (node.type === 'Program') {
674
+ break;
675
+ }
676
+ current = current.parentPath;
677
+ }
678
+ // If no class found, it's at module level (global scope)
679
+ if (scopePath.length === 0) {
680
+ scopePath.push('global');
205
681
  }
206
- // For arrow functions and other cases, we can't perfectly match the ID
207
- // because FunctionVisitor uses a counter. For now, use module.id as fallback
208
- // to avoid creating invalid edges. The CALL node will be connected to MODULE
209
- // instead of the specific function.
210
- return module.id;
682
+ // Compute semantic ID: {file}->{scopePath}->FUNCTION->{name}
683
+ return `${module.file}->${scopePath.join('->')}->FUNCTION->${funcName}`;
211
684
  }
212
685
  getHandlers() {
213
686
  const { module } = this;
@@ -220,6 +693,7 @@ export class CallExpressionVisitor extends ASTVisitor {
220
693
  const callSiteCounterRef = (this.collections.callSiteCounterRef ?? { value: 0 });
221
694
  const literalCounterRef = (this.collections.literalCounterRef ?? { value: 0 });
222
695
  const processedNodes = this.collections.processedNodes ?? { callSites: new Set(), methodCalls: new Set(), eventListeners: new Set() };
696
+ const scopeTracker = this.scopeTracker;
223
697
  return {
224
698
  CallExpression: (path) => {
225
699
  const callNode = path.node;
@@ -227,16 +701,24 @@ export class CallExpressionVisitor extends ASTVisitor {
227
701
  // Determine parent scope - if inside a function, use function's scope, otherwise module
228
702
  const parentScopeId = functionParent ? this.getFunctionScopeId(functionParent, module) : module.id;
229
703
  // Identifier calls (direct function calls)
704
+ // Skip if inside function - they will be processed by analyzeFunctionBody with proper scope tracking
230
705
  if (callNode.callee.type === 'Identifier') {
706
+ if (functionParent) {
707
+ return;
708
+ }
231
709
  const callee = callNode.callee;
232
- const callId = `CALL#${callee.name}#${module.file}#${callNode.loc.start.line}:${callNode.loc.start.column}:${callSiteCounterRef.value++}`;
710
+ const line = getLine(callNode);
711
+ const column = getColumn(callNode);
712
+ // Generate ID using centralized IdGenerator
713
+ const idGenerator = new IdGenerator(scopeTracker);
714
+ const callId = idGenerator.generate('CALL', callee.name, module.file, line, column, callSiteCounterRef, { useDiscriminator: true, discriminatorKey: `CALL:${callee.name}` });
233
715
  callSites.push({
234
716
  id: callId,
235
717
  type: 'CALL',
236
718
  name: callee.name,
237
719
  file: module.file,
238
- line: callNode.loc.start.line,
239
- column: callNode.loc.start.column,
720
+ line,
721
+ column,
240
722
  parentScopeId,
241
723
  targetFunctionName: callee.name
242
724
  });
@@ -245,8 +727,12 @@ export class CallExpressionVisitor extends ASTVisitor {
245
727
  this.extractArguments(callNode.arguments, callId, module, callArguments, literals, literalCounterRef);
246
728
  }
247
729
  }
248
- // MemberExpression calls (method calls at module level)
730
+ // MemberExpression calls (method calls)
731
+ // Skip if inside function - they will be processed by analyzeFunctionBody with proper scope tracking
249
732
  else if (callNode.callee.type === 'MemberExpression') {
733
+ if (functionParent) {
734
+ return;
735
+ }
250
736
  const memberCallee = callNode.callee;
251
737
  const object = memberCallee.object;
252
738
  const property = memberCallee.property;
@@ -268,13 +754,15 @@ export class CallExpressionVisitor extends ASTVisitor {
268
754
  return;
269
755
  }
270
756
  processedNodes.eventListeners.add(nodeKey);
757
+ const eventLine = getLine(callNode);
758
+ const eventColumn = getColumn(callNode);
271
759
  eventListeners.push({
272
- id: `event:listener#${eventName}#${module.file}#${callNode.loc.start.line}:${callNode.loc.start.column}:${callSiteCounterRef.value++}`,
760
+ id: `event:listener#${eventName}#${module.file}#${eventLine}:${eventColumn}:${callSiteCounterRef.value++}`,
273
761
  type: 'event:listener',
274
762
  name: eventName,
275
763
  object: objectName,
276
764
  file: module.file,
277
- line: callNode.loc.start.line,
765
+ line: eventLine,
278
766
  parentScopeId,
279
767
  callbackArg: secondArg
280
768
  });
@@ -288,7 +776,11 @@ export class CallExpressionVisitor extends ASTVisitor {
288
776
  }
289
777
  processedNodes.methodCalls.add(nodeKey);
290
778
  const fullName = `${objectName}.${methodName}`;
291
- const methodCallId = `CALL#${fullName}#${module.file}#${callNode.loc.start.line}:${callNode.loc.start.column}:${callSiteCounterRef.value++}`;
779
+ const methodLine = getLine(callNode);
780
+ const methodColumn = getColumn(callNode);
781
+ // Generate ID using centralized IdGenerator
782
+ const idGenerator = new IdGenerator(scopeTracker);
783
+ const methodCallId = idGenerator.generate('CALL', fullName, module.file, methodLine, methodColumn, callSiteCounterRef, { useDiscriminator: true, discriminatorKey: `CALL:${fullName}` });
292
784
  methodCalls.push({
293
785
  id: methodCallId,
294
786
  type: 'CALL',
@@ -298,10 +790,19 @@ export class CallExpressionVisitor extends ASTVisitor {
298
790
  computed: isComputed,
299
791
  computedPropertyVar, // Variable name used in obj[x]() calls
300
792
  file: module.file,
301
- line: callNode.loc.start.line,
302
- column: callNode.loc.start.column,
793
+ line: methodLine,
794
+ column: methodColumn,
303
795
  parentScopeId
304
796
  });
797
+ // Check for array mutation methods (push, unshift, splice)
798
+ const ARRAY_MUTATION_METHODS = ['push', 'unshift', 'splice'];
799
+ if (ARRAY_MUTATION_METHODS.includes(methodName)) {
800
+ this.detectArrayMutation(callNode, objectName, methodName, module);
801
+ }
802
+ // Check for Object.assign() calls
803
+ if (objectName === 'Object' && methodName === 'assign') {
804
+ this.detectObjectAssign(callNode, module);
805
+ }
305
806
  // Extract arguments for PASSES_ARGUMENT edges
306
807
  if (callNode.arguments.length > 0) {
307
808
  this.extractArguments(callNode.arguments, methodCallId, module, callArguments, literals, literalCounterRef);
@@ -310,8 +811,8 @@ export class CallExpressionVisitor extends ASTVisitor {
310
811
  if (arg.type === 'ArrowFunctionExpression' || arg.type === 'FunctionExpression') {
311
812
  methodCallbacks.push({
312
813
  methodCallId,
313
- callbackLine: arg.loc.start.line,
314
- callbackColumn: arg.loc.start.column,
814
+ callbackLine: getLine(arg),
815
+ callbackColumn: getColumn(arg),
315
816
  callbackType: arg.type
316
817
  });
317
818
  }
@@ -319,13 +820,40 @@ export class CallExpressionVisitor extends ASTVisitor {
319
820
  }
320
821
  }
321
822
  }
823
+ // REG-117: Nested array mutations like obj.arr.push(item)
824
+ // object is MemberExpression, property is the method name
825
+ else if (object.type === 'MemberExpression' && property.type === 'Identifier') {
826
+ const nestedMember = object;
827
+ const methodName = property.name;
828
+ const ARRAY_MUTATION_METHODS = ['push', 'unshift', 'splice'];
829
+ if (ARRAY_MUTATION_METHODS.includes(methodName)) {
830
+ // Extract base object and property from nested MemberExpression
831
+ const base = nestedMember.object;
832
+ const prop = nestedMember.property;
833
+ // Only handle single-level nesting: obj.arr.push() or this.items.push()
834
+ if ((base.type === 'Identifier' || base.type === 'ThisExpression') &&
835
+ !nestedMember.computed &&
836
+ prop.type === 'Identifier') {
837
+ const baseObjectName = base.type === 'Identifier' ? base.name : 'this';
838
+ const propertyName = prop.name;
839
+ this.detectArrayMutation(callNode, `${baseObjectName}.${propertyName}`, // arrayName for ID purposes
840
+ methodName, module, true, // isNested
841
+ baseObjectName, propertyName);
842
+ }
843
+ }
844
+ }
322
845
  }
323
846
  },
324
847
  // NewExpression: new Foo(), new Function(), new Map(), etc.
848
+ // Skip if inside function - they will be processed by analyzeFunctionBody with proper scope tracking
325
849
  NewExpression: (path) => {
326
850
  const newNode = path.node;
327
851
  const functionParent = path.getFunctionParent();
328
- const parentScopeId = functionParent ? this.getFunctionScopeId(functionParent, module) : module.id;
852
+ // Skip if inside function - handled by analyzeFunctionBody
853
+ if (functionParent) {
854
+ return;
855
+ }
856
+ const parentScopeId = module.id;
329
857
  // Dedup check
330
858
  const nodeKey = `new:${newNode.start}:${newNode.end}`;
331
859
  if (processedNodes.methodCalls.has(nodeKey)) {
@@ -336,13 +864,18 @@ export class CallExpressionVisitor extends ASTVisitor {
336
864
  if (newNode.callee.type === 'Identifier') {
337
865
  const callee = newNode.callee;
338
866
  const constructorName = callee.name;
867
+ const newLine = getLine(newNode);
868
+ const newColumn = getColumn(newNode);
869
+ // Generate ID using centralized IdGenerator
870
+ const idGenerator = new IdGenerator(scopeTracker);
871
+ const newCallId = idGenerator.generate('CALL', `new:${constructorName}`, module.file, newLine, newColumn, callSiteCounterRef, { useDiscriminator: true, discriminatorKey: `CALL:new:${constructorName}` });
339
872
  callSites.push({
340
- id: `CALL#new:${constructorName}#${module.file}#${newNode.loc.start.line}:${newNode.loc.start.column}:${callSiteCounterRef.value++}`,
873
+ id: newCallId,
341
874
  type: 'CALL',
342
875
  name: constructorName,
343
876
  file: module.file,
344
- line: newNode.loc.start.line,
345
- column: newNode.loc.start.column,
877
+ line: newLine,
878
+ column: newColumn,
346
879
  parentScopeId,
347
880
  targetFunctionName: constructorName,
348
881
  isNew: true // Mark as constructor call
@@ -357,15 +890,20 @@ export class CallExpressionVisitor extends ASTVisitor {
357
890
  const objectName = object.name;
358
891
  const constructorName = property.name;
359
892
  const fullName = `${objectName}.${constructorName}`;
893
+ const memberNewLine = getLine(newNode);
894
+ const memberNewColumn = getColumn(newNode);
895
+ // Generate ID using centralized IdGenerator
896
+ const idGenerator = new IdGenerator(scopeTracker);
897
+ const newMethodCallId = idGenerator.generate('CALL', `new:${fullName}`, module.file, memberNewLine, memberNewColumn, callSiteCounterRef, { useDiscriminator: true, discriminatorKey: `CALL:new:${fullName}` });
360
898
  methodCalls.push({
361
- id: `CALL#new:${fullName}#${module.file}#${newNode.loc.start.line}:${newNode.loc.start.column}:${callSiteCounterRef.value++}`,
899
+ id: newMethodCallId,
362
900
  type: 'CALL',
363
901
  name: fullName,
364
902
  object: objectName,
365
903
  method: constructorName,
366
904
  file: module.file,
367
- line: newNode.loc.start.line,
368
- column: newNode.loc.start.column,
905
+ line: memberNewLine,
906
+ column: memberNewColumn,
369
907
  parentScopeId,
370
908
  isNew: true // Mark as constructor call
371
909
  });