driftdetect-core 0.4.5 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (578) hide show
  1. package/LICENSE +21 -0
  2. package/dist/boundaries/boundary-scanner.d.ts.map +1 -1
  3. package/dist/boundaries/boundary-scanner.js +184 -18
  4. package/dist/boundaries/boundary-scanner.js.map +1 -1
  5. package/dist/boundaries/types.d.ts +34 -2
  6. package/dist/boundaries/types.d.ts.map +1 -1
  7. package/dist/call-graph/analysis/graph-builder.d.ts +3 -0
  8. package/dist/call-graph/analysis/graph-builder.d.ts.map +1 -1
  9. package/dist/call-graph/analysis/graph-builder.js +81 -18
  10. package/dist/call-graph/analysis/graph-builder.js.map +1 -1
  11. package/dist/call-graph/extractors/csharp-data-access-extractor.d.ts +8 -0
  12. package/dist/call-graph/extractors/csharp-data-access-extractor.d.ts.map +1 -1
  13. package/dist/call-graph/extractors/csharp-data-access-extractor.js +18 -5
  14. package/dist/call-graph/extractors/csharp-data-access-extractor.js.map +1 -1
  15. package/dist/call-graph/extractors/csharp-extractor.d.ts +35 -0
  16. package/dist/call-graph/extractors/csharp-extractor.d.ts.map +1 -1
  17. package/dist/call-graph/extractors/csharp-extractor.js +362 -4
  18. package/dist/call-graph/extractors/csharp-extractor.js.map +1 -1
  19. package/dist/call-graph/extractors/csharp-hybrid-extractor.d.ts +37 -0
  20. package/dist/call-graph/extractors/csharp-hybrid-extractor.d.ts.map +1 -0
  21. package/dist/call-graph/extractors/csharp-hybrid-extractor.js +408 -0
  22. package/dist/call-graph/extractors/csharp-hybrid-extractor.js.map +1 -0
  23. package/dist/call-graph/extractors/data-access-extractor.d.ts +16 -2
  24. package/dist/call-graph/extractors/data-access-extractor.d.ts.map +1 -1
  25. package/dist/call-graph/extractors/data-access-extractor.js +114 -5
  26. package/dist/call-graph/extractors/data-access-extractor.js.map +1 -1
  27. package/dist/call-graph/extractors/hybrid-extractor-base.d.ts +102 -0
  28. package/dist/call-graph/extractors/hybrid-extractor-base.d.ts.map +1 -0
  29. package/dist/call-graph/extractors/hybrid-extractor-base.js +289 -0
  30. package/dist/call-graph/extractors/hybrid-extractor-base.js.map +1 -0
  31. package/dist/call-graph/extractors/index.d.ts +17 -13
  32. package/dist/call-graph/extractors/index.d.ts.map +1 -1
  33. package/dist/call-graph/extractors/index.js +24 -23
  34. package/dist/call-graph/extractors/index.js.map +1 -1
  35. package/dist/call-graph/extractors/java-data-access-extractor.d.ts +8 -0
  36. package/dist/call-graph/extractors/java-data-access-extractor.d.ts.map +1 -1
  37. package/dist/call-graph/extractors/java-data-access-extractor.js +20 -6
  38. package/dist/call-graph/extractors/java-data-access-extractor.js.map +1 -1
  39. package/dist/call-graph/extractors/java-extractor.d.ts +15 -0
  40. package/dist/call-graph/extractors/java-extractor.d.ts.map +1 -1
  41. package/dist/call-graph/extractors/java-extractor.js +120 -4
  42. package/dist/call-graph/extractors/java-extractor.js.map +1 -1
  43. package/dist/call-graph/extractors/java-hybrid-extractor.d.ts +36 -0
  44. package/dist/call-graph/extractors/java-hybrid-extractor.d.ts.map +1 -0
  45. package/dist/call-graph/extractors/java-hybrid-extractor.js +426 -0
  46. package/dist/call-graph/extractors/java-hybrid-extractor.js.map +1 -0
  47. package/dist/call-graph/extractors/php-data-access-extractor.d.ts +8 -0
  48. package/dist/call-graph/extractors/php-data-access-extractor.d.ts.map +1 -1
  49. package/dist/call-graph/extractors/php-data-access-extractor.js +20 -6
  50. package/dist/call-graph/extractors/php-data-access-extractor.js.map +1 -1
  51. package/dist/call-graph/extractors/php-extractor.d.ts +48 -1
  52. package/dist/call-graph/extractors/php-extractor.d.ts.map +1 -1
  53. package/dist/call-graph/extractors/php-extractor.js +460 -6
  54. package/dist/call-graph/extractors/php-extractor.js.map +1 -1
  55. package/dist/call-graph/extractors/php-hybrid-extractor.d.ts +35 -0
  56. package/dist/call-graph/extractors/php-hybrid-extractor.d.ts.map +1 -0
  57. package/dist/call-graph/extractors/php-hybrid-extractor.js +393 -0
  58. package/dist/call-graph/extractors/php-hybrid-extractor.js.map +1 -0
  59. package/dist/call-graph/extractors/python-data-access-extractor.d.ts +8 -0
  60. package/dist/call-graph/extractors/python-data-access-extractor.d.ts.map +1 -1
  61. package/dist/call-graph/extractors/python-data-access-extractor.js +20 -6
  62. package/dist/call-graph/extractors/python-data-access-extractor.js.map +1 -1
  63. package/dist/call-graph/extractors/python-hybrid-extractor.d.ts +85 -0
  64. package/dist/call-graph/extractors/python-hybrid-extractor.d.ts.map +1 -0
  65. package/dist/call-graph/extractors/python-hybrid-extractor.js +462 -0
  66. package/dist/call-graph/extractors/python-hybrid-extractor.js.map +1 -0
  67. package/dist/call-graph/extractors/regex/base-regex-extractor.d.ts +154 -0
  68. package/dist/call-graph/extractors/regex/base-regex-extractor.d.ts.map +1 -0
  69. package/dist/call-graph/extractors/regex/base-regex-extractor.js +346 -0
  70. package/dist/call-graph/extractors/regex/base-regex-extractor.js.map +1 -0
  71. package/dist/call-graph/extractors/regex/csharp-regex.d.ts +34 -0
  72. package/dist/call-graph/extractors/regex/csharp-regex.d.ts.map +1 -0
  73. package/dist/call-graph/extractors/regex/csharp-regex.js +393 -0
  74. package/dist/call-graph/extractors/regex/csharp-regex.js.map +1 -0
  75. package/dist/call-graph/extractors/regex/index.d.ts +25 -0
  76. package/dist/call-graph/extractors/regex/index.d.ts.map +1 -0
  77. package/dist/call-graph/extractors/regex/index.js +66 -0
  78. package/dist/call-graph/extractors/regex/index.js.map +1 -0
  79. package/dist/call-graph/extractors/regex/java-regex.d.ts +34 -0
  80. package/dist/call-graph/extractors/regex/java-regex.d.ts.map +1 -0
  81. package/dist/call-graph/extractors/regex/java-regex.js +327 -0
  82. package/dist/call-graph/extractors/regex/java-regex.js.map +1 -0
  83. package/dist/call-graph/extractors/regex/php-regex.d.ts +30 -0
  84. package/dist/call-graph/extractors/regex/php-regex.d.ts.map +1 -0
  85. package/dist/call-graph/extractors/regex/php-regex.js +333 -0
  86. package/dist/call-graph/extractors/regex/php-regex.js.map +1 -0
  87. package/dist/call-graph/extractors/regex/python-regex.d.ts +46 -0
  88. package/dist/call-graph/extractors/regex/python-regex.d.ts.map +1 -0
  89. package/dist/call-graph/extractors/regex/python-regex.js +380 -0
  90. package/dist/call-graph/extractors/regex/python-regex.js.map +1 -0
  91. package/dist/call-graph/extractors/regex/typescript-regex.d.ts +27 -0
  92. package/dist/call-graph/extractors/regex/typescript-regex.d.ts.map +1 -0
  93. package/dist/call-graph/extractors/regex/typescript-regex.js +349 -0
  94. package/dist/call-graph/extractors/regex/typescript-regex.js.map +1 -0
  95. package/dist/call-graph/extractors/semantic-data-access-scanner.d.ts +11 -0
  96. package/dist/call-graph/extractors/semantic-data-access-scanner.d.ts.map +1 -1
  97. package/dist/call-graph/extractors/semantic-data-access-scanner.js +53 -2
  98. package/dist/call-graph/extractors/semantic-data-access-scanner.js.map +1 -1
  99. package/dist/call-graph/extractors/types.d.ts +111 -0
  100. package/dist/call-graph/extractors/types.d.ts.map +1 -0
  101. package/dist/call-graph/extractors/types.js +68 -0
  102. package/dist/call-graph/extractors/types.js.map +1 -0
  103. package/dist/call-graph/extractors/typescript-data-access-extractor.d.ts +8 -0
  104. package/dist/call-graph/extractors/typescript-data-access-extractor.d.ts.map +1 -1
  105. package/dist/call-graph/extractors/typescript-data-access-extractor.js +31 -10
  106. package/dist/call-graph/extractors/typescript-data-access-extractor.js.map +1 -1
  107. package/dist/call-graph/extractors/typescript-hybrid-extractor.d.ts +116 -0
  108. package/dist/call-graph/extractors/typescript-hybrid-extractor.d.ts.map +1 -0
  109. package/dist/call-graph/extractors/typescript-hybrid-extractor.js +635 -0
  110. package/dist/call-graph/extractors/typescript-hybrid-extractor.js.map +1 -0
  111. package/dist/call-graph/index.d.ts +2 -4
  112. package/dist/call-graph/index.d.ts.map +1 -1
  113. package/dist/call-graph/index.js +5 -6
  114. package/dist/call-graph/index.js.map +1 -1
  115. package/dist/error-handling/error-handling-analyzer.d.ts +73 -0
  116. package/dist/error-handling/error-handling-analyzer.d.ts.map +1 -0
  117. package/dist/error-handling/error-handling-analyzer.js +706 -0
  118. package/dist/error-handling/error-handling-analyzer.js.map +1 -0
  119. package/dist/error-handling/index.d.ts +8 -0
  120. package/dist/error-handling/index.d.ts.map +1 -0
  121. package/dist/error-handling/index.js +8 -0
  122. package/dist/error-handling/index.js.map +1 -0
  123. package/dist/error-handling/types.d.ts +307 -0
  124. package/dist/error-handling/types.d.ts.map +1 -0
  125. package/dist/error-handling/types.js +7 -0
  126. package/dist/error-handling/types.js.map +1 -0
  127. package/dist/index.d.ts +18 -2
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +44 -5
  130. package/dist/index.js.map +1 -1
  131. package/dist/lake/pattern-shard-store.d.ts +6 -0
  132. package/dist/lake/pattern-shard-store.d.ts.map +1 -1
  133. package/dist/lake/pattern-shard-store.js +6 -0
  134. package/dist/lake/pattern-shard-store.js.map +1 -1
  135. package/dist/language-intelligence/base-normalizer.d.ts +68 -0
  136. package/dist/language-intelligence/base-normalizer.d.ts.map +1 -0
  137. package/dist/language-intelligence/base-normalizer.js +210 -0
  138. package/dist/language-intelligence/base-normalizer.js.map +1 -0
  139. package/dist/language-intelligence/framework-registry.d.ts +89 -0
  140. package/dist/language-intelligence/framework-registry.d.ts.map +1 -0
  141. package/dist/language-intelligence/framework-registry.js +165 -0
  142. package/dist/language-intelligence/framework-registry.js.map +1 -0
  143. package/dist/language-intelligence/frameworks/aspnet.d.ts +11 -0
  144. package/dist/language-intelligence/frameworks/aspnet.d.ts.map +1 -0
  145. package/dist/language-intelligence/frameworks/aspnet.js +325 -0
  146. package/dist/language-intelligence/frameworks/aspnet.js.map +1 -0
  147. package/dist/language-intelligence/frameworks/fastapi.d.ts +11 -0
  148. package/dist/language-intelligence/frameworks/fastapi.d.ts.map +1 -0
  149. package/dist/language-intelligence/frameworks/fastapi.js +188 -0
  150. package/dist/language-intelligence/frameworks/fastapi.js.map +1 -0
  151. package/dist/language-intelligence/frameworks/index.d.ts +32 -0
  152. package/dist/language-intelligence/frameworks/index.d.ts.map +1 -0
  153. package/dist/language-intelligence/frameworks/index.js +51 -0
  154. package/dist/language-intelligence/frameworks/index.js.map +1 -0
  155. package/dist/language-intelligence/frameworks/laravel.d.ts +12 -0
  156. package/dist/language-intelligence/frameworks/laravel.d.ts.map +1 -0
  157. package/dist/language-intelligence/frameworks/laravel.js +194 -0
  158. package/dist/language-intelligence/frameworks/laravel.js.map +1 -0
  159. package/dist/language-intelligence/frameworks/nestjs.d.ts +11 -0
  160. package/dist/language-intelligence/frameworks/nestjs.d.ts.map +1 -0
  161. package/dist/language-intelligence/frameworks/nestjs.js +307 -0
  162. package/dist/language-intelligence/frameworks/nestjs.js.map +1 -0
  163. package/dist/language-intelligence/frameworks/spring.d.ts +11 -0
  164. package/dist/language-intelligence/frameworks/spring.d.ts.map +1 -0
  165. package/dist/language-intelligence/frameworks/spring.js +369 -0
  166. package/dist/language-intelligence/frameworks/spring.js.map +1 -0
  167. package/dist/language-intelligence/index.d.ts +33 -0
  168. package/dist/language-intelligence/index.d.ts.map +1 -0
  169. package/dist/language-intelligence/index.js +37 -0
  170. package/dist/language-intelligence/index.js.map +1 -0
  171. package/dist/language-intelligence/language-intelligence.d.ts +99 -0
  172. package/dist/language-intelligence/language-intelligence.d.ts.map +1 -0
  173. package/dist/language-intelligence/language-intelligence.js +239 -0
  174. package/dist/language-intelligence/language-intelligence.js.map +1 -0
  175. package/dist/language-intelligence/normalizers/csharp-normalizer.d.ts +39 -0
  176. package/dist/language-intelligence/normalizers/csharp-normalizer.d.ts.map +1 -0
  177. package/dist/language-intelligence/normalizers/csharp-normalizer.js +86 -0
  178. package/dist/language-intelligence/normalizers/csharp-normalizer.js.map +1 -0
  179. package/dist/language-intelligence/normalizers/index.d.ts +25 -0
  180. package/dist/language-intelligence/normalizers/index.d.ts.map +1 -0
  181. package/dist/language-intelligence/normalizers/index.js +60 -0
  182. package/dist/language-intelligence/normalizers/index.js.map +1 -0
  183. package/dist/language-intelligence/normalizers/java-normalizer.d.ts +39 -0
  184. package/dist/language-intelligence/normalizers/java-normalizer.d.ts.map +1 -0
  185. package/dist/language-intelligence/normalizers/java-normalizer.js +96 -0
  186. package/dist/language-intelligence/normalizers/java-normalizer.js.map +1 -0
  187. package/dist/language-intelligence/normalizers/php-normalizer.d.ts +39 -0
  188. package/dist/language-intelligence/normalizers/php-normalizer.d.ts.map +1 -0
  189. package/dist/language-intelligence/normalizers/php-normalizer.js +86 -0
  190. package/dist/language-intelligence/normalizers/php-normalizer.js.map +1 -0
  191. package/dist/language-intelligence/normalizers/python-normalizer.d.ts +39 -0
  192. package/dist/language-intelligence/normalizers/python-normalizer.d.ts.map +1 -0
  193. package/dist/language-intelligence/normalizers/python-normalizer.js +95 -0
  194. package/dist/language-intelligence/normalizers/python-normalizer.js.map +1 -0
  195. package/dist/language-intelligence/normalizers/typescript-normalizer.d.ts +39 -0
  196. package/dist/language-intelligence/normalizers/typescript-normalizer.d.ts.map +1 -0
  197. package/dist/language-intelligence/normalizers/typescript-normalizer.js +84 -0
  198. package/dist/language-intelligence/normalizers/typescript-normalizer.js.map +1 -0
  199. package/dist/language-intelligence/types.d.ts +270 -0
  200. package/dist/language-intelligence/types.d.ts.map +1 -0
  201. package/dist/language-intelligence/types.js +9 -0
  202. package/dist/language-intelligence/types.js.map +1 -0
  203. package/dist/module-coupling/coupling-analyzer.d.ts +73 -0
  204. package/dist/module-coupling/coupling-analyzer.d.ts.map +1 -0
  205. package/dist/module-coupling/coupling-analyzer.js +668 -0
  206. package/dist/module-coupling/coupling-analyzer.js.map +1 -0
  207. package/dist/module-coupling/index.d.ts +9 -0
  208. package/dist/module-coupling/index.d.ts.map +1 -0
  209. package/dist/module-coupling/index.js +9 -0
  210. package/dist/module-coupling/index.js.map +1 -0
  211. package/dist/module-coupling/types.d.ts +273 -0
  212. package/dist/module-coupling/types.d.ts.map +1 -0
  213. package/dist/module-coupling/types.js +8 -0
  214. package/dist/module-coupling/types.js.map +1 -0
  215. package/dist/patterns/adapters/index.d.ts +11 -0
  216. package/dist/patterns/adapters/index.d.ts.map +1 -0
  217. package/dist/patterns/adapters/index.js +11 -0
  218. package/dist/patterns/adapters/index.js.map +1 -0
  219. package/dist/patterns/adapters/pattern-store-adapter.d.ts +59 -0
  220. package/dist/patterns/adapters/pattern-store-adapter.d.ts.map +1 -0
  221. package/dist/patterns/adapters/pattern-store-adapter.js +468 -0
  222. package/dist/patterns/adapters/pattern-store-adapter.js.map +1 -0
  223. package/dist/patterns/adapters/service-factory.d.ts +40 -0
  224. package/dist/patterns/adapters/service-factory.d.ts.map +1 -0
  225. package/dist/patterns/adapters/service-factory.js +144 -0
  226. package/dist/patterns/adapters/service-factory.js.map +1 -0
  227. package/dist/patterns/errors.d.ts +32 -0
  228. package/dist/patterns/errors.d.ts.map +1 -0
  229. package/dist/patterns/errors.js +45 -0
  230. package/dist/patterns/errors.js.map +1 -0
  231. package/dist/patterns/impl/cached-repository.d.ts +79 -0
  232. package/dist/patterns/impl/cached-repository.d.ts.map +1 -0
  233. package/dist/patterns/impl/cached-repository.js +296 -0
  234. package/dist/patterns/impl/cached-repository.js.map +1 -0
  235. package/dist/patterns/impl/file-repository.d.ts +75 -0
  236. package/dist/patterns/impl/file-repository.d.ts.map +1 -0
  237. package/dist/patterns/impl/file-repository.js +507 -0
  238. package/dist/patterns/impl/file-repository.js.map +1 -0
  239. package/dist/patterns/impl/index.d.ts +16 -0
  240. package/dist/patterns/impl/index.d.ts.map +1 -0
  241. package/dist/patterns/impl/index.js +21 -0
  242. package/dist/patterns/impl/index.js.map +1 -0
  243. package/dist/patterns/impl/memory-repository.d.ts +56 -0
  244. package/dist/patterns/impl/memory-repository.d.ts.map +1 -0
  245. package/dist/patterns/impl/memory-repository.js +323 -0
  246. package/dist/patterns/impl/memory-repository.js.map +1 -0
  247. package/dist/patterns/impl/pattern-service.d.ts +52 -0
  248. package/dist/patterns/impl/pattern-service.d.ts.map +1 -0
  249. package/dist/patterns/impl/pattern-service.js +382 -0
  250. package/dist/patterns/impl/pattern-service.js.map +1 -0
  251. package/dist/patterns/impl/repository-factory.d.ts +44 -0
  252. package/dist/patterns/impl/repository-factory.d.ts.map +1 -0
  253. package/dist/patterns/impl/repository-factory.js +140 -0
  254. package/dist/patterns/impl/repository-factory.js.map +1 -0
  255. package/dist/patterns/impl/unified-file-repository.d.ts +111 -0
  256. package/dist/patterns/impl/unified-file-repository.d.ts.map +1 -0
  257. package/dist/patterns/impl/unified-file-repository.js +677 -0
  258. package/dist/patterns/impl/unified-file-repository.js.map +1 -0
  259. package/dist/patterns/index.d.ts +23 -0
  260. package/dist/patterns/index.d.ts.map +1 -0
  261. package/dist/patterns/index.js +41 -0
  262. package/dist/patterns/index.js.map +1 -0
  263. package/dist/patterns/repository.d.ts +241 -0
  264. package/dist/patterns/repository.d.ts.map +1 -0
  265. package/dist/patterns/repository.js +23 -0
  266. package/dist/patterns/repository.js.map +1 -0
  267. package/dist/patterns/service.d.ts +245 -0
  268. package/dist/patterns/service.d.ts.map +1 -0
  269. package/dist/patterns/service.js +25 -0
  270. package/dist/patterns/service.js.map +1 -0
  271. package/dist/patterns/types.d.ts +227 -0
  272. package/dist/patterns/types.d.ts.map +1 -0
  273. package/dist/patterns/types.js +117 -0
  274. package/dist/patterns/types.js.map +1 -0
  275. package/dist/scanner/file-processor-worker.d.ts +66 -0
  276. package/dist/scanner/file-processor-worker.d.ts.map +1 -0
  277. package/dist/scanner/file-processor-worker.js +189 -0
  278. package/dist/scanner/file-processor-worker.js.map +1 -0
  279. package/dist/scanner/index.d.ts +2 -0
  280. package/dist/scanner/index.d.ts.map +1 -1
  281. package/dist/scanner/index.js +2 -0
  282. package/dist/scanner/index.js.map +1 -1
  283. package/dist/scanner/threaded-worker-pool.d.ts +182 -0
  284. package/dist/scanner/threaded-worker-pool.d.ts.map +1 -0
  285. package/dist/scanner/threaded-worker-pool.js +243 -0
  286. package/dist/scanner/threaded-worker-pool.js.map +1 -0
  287. package/dist/store/pattern-store.d.ts +6 -0
  288. package/dist/store/pattern-store.d.ts.map +1 -1
  289. package/dist/store/pattern-store.js +6 -0
  290. package/dist/store/pattern-store.js.map +1 -1
  291. package/dist/store/types.d.ts +6 -3
  292. package/dist/store/types.d.ts.map +1 -1
  293. package/dist/store/types.js.map +1 -1
  294. package/dist/test-topology/extractors/base-test-extractor.d.ts +89 -0
  295. package/dist/test-topology/extractors/base-test-extractor.d.ts.map +1 -0
  296. package/dist/test-topology/extractors/base-test-extractor.js +187 -0
  297. package/dist/test-topology/extractors/base-test-extractor.js.map +1 -0
  298. package/dist/test-topology/extractors/csharp-test-extractor.d.ts +23 -0
  299. package/dist/test-topology/extractors/csharp-test-extractor.d.ts.map +1 -0
  300. package/dist/test-topology/extractors/csharp-test-extractor.js +367 -0
  301. package/dist/test-topology/extractors/csharp-test-extractor.js.map +1 -0
  302. package/dist/test-topology/extractors/index.d.ts +12 -0
  303. package/dist/test-topology/extractors/index.d.ts.map +1 -0
  304. package/dist/test-topology/extractors/index.js +12 -0
  305. package/dist/test-topology/extractors/index.js.map +1 -0
  306. package/dist/test-topology/extractors/java-test-extractor.d.ts +20 -0
  307. package/dist/test-topology/extractors/java-test-extractor.d.ts.map +1 -0
  308. package/dist/test-topology/extractors/java-test-extractor.js +275 -0
  309. package/dist/test-topology/extractors/java-test-extractor.js.map +1 -0
  310. package/dist/test-topology/extractors/php-test-extractor.d.ts +24 -0
  311. package/dist/test-topology/extractors/php-test-extractor.d.ts.map +1 -0
  312. package/dist/test-topology/extractors/php-test-extractor.js +409 -0
  313. package/dist/test-topology/extractors/php-test-extractor.js.map +1 -0
  314. package/dist/test-topology/extractors/python-test-extractor.d.ts +23 -0
  315. package/dist/test-topology/extractors/python-test-extractor.d.ts.map +1 -0
  316. package/dist/test-topology/extractors/python-test-extractor.js +342 -0
  317. package/dist/test-topology/extractors/python-test-extractor.js.map +1 -0
  318. package/dist/test-topology/extractors/regex/csharp-test-regex.d.ts +51 -0
  319. package/dist/test-topology/extractors/regex/csharp-test-regex.d.ts.map +1 -0
  320. package/dist/test-topology/extractors/regex/csharp-test-regex.js +383 -0
  321. package/dist/test-topology/extractors/regex/csharp-test-regex.js.map +1 -0
  322. package/dist/test-topology/extractors/regex/index.d.ts +18 -0
  323. package/dist/test-topology/extractors/regex/index.d.ts.map +1 -0
  324. package/dist/test-topology/extractors/regex/index.js +43 -0
  325. package/dist/test-topology/extractors/regex/index.js.map +1 -0
  326. package/dist/test-topology/extractors/regex/java-test-regex.d.ts +50 -0
  327. package/dist/test-topology/extractors/regex/java-test-regex.d.ts.map +1 -0
  328. package/dist/test-topology/extractors/regex/java-test-regex.js +370 -0
  329. package/dist/test-topology/extractors/regex/java-test-regex.js.map +1 -0
  330. package/dist/test-topology/extractors/regex/php-test-regex.d.ts +56 -0
  331. package/dist/test-topology/extractors/regex/php-test-regex.d.ts.map +1 -0
  332. package/dist/test-topology/extractors/regex/php-test-regex.js +503 -0
  333. package/dist/test-topology/extractors/regex/php-test-regex.js.map +1 -0
  334. package/dist/test-topology/extractors/regex/python-test-regex.d.ts +57 -0
  335. package/dist/test-topology/extractors/regex/python-test-regex.d.ts.map +1 -0
  336. package/dist/test-topology/extractors/regex/python-test-regex.js +381 -0
  337. package/dist/test-topology/extractors/regex/python-test-regex.js.map +1 -0
  338. package/dist/test-topology/extractors/regex/typescript-test-regex.d.ts +60 -0
  339. package/dist/test-topology/extractors/regex/typescript-test-regex.d.ts.map +1 -0
  340. package/dist/test-topology/extractors/regex/typescript-test-regex.js +368 -0
  341. package/dist/test-topology/extractors/regex/typescript-test-regex.js.map +1 -0
  342. package/dist/test-topology/extractors/typescript-test-extractor.d.ts +24 -0
  343. package/dist/test-topology/extractors/typescript-test-extractor.d.ts.map +1 -0
  344. package/dist/test-topology/extractors/typescript-test-extractor.js +266 -0
  345. package/dist/test-topology/extractors/typescript-test-extractor.js.map +1 -0
  346. package/dist/test-topology/hybrid-test-topology-analyzer.d.ts +98 -0
  347. package/dist/test-topology/hybrid-test-topology-analyzer.d.ts.map +1 -0
  348. package/dist/test-topology/hybrid-test-topology-analyzer.js +555 -0
  349. package/dist/test-topology/hybrid-test-topology-analyzer.js.map +1 -0
  350. package/dist/test-topology/index.d.ts +16 -0
  351. package/dist/test-topology/index.d.ts.map +1 -0
  352. package/dist/test-topology/index.js +19 -0
  353. package/dist/test-topology/index.js.map +1 -0
  354. package/dist/test-topology/test-topology-analyzer.d.ts +85 -0
  355. package/dist/test-topology/test-topology-analyzer.d.ts.map +1 -0
  356. package/dist/test-topology/test-topology-analyzer.js +538 -0
  357. package/dist/test-topology/test-topology-analyzer.js.map +1 -0
  358. package/dist/test-topology/types.d.ts +300 -0
  359. package/dist/test-topology/types.d.ts.map +1 -0
  360. package/dist/test-topology/types.js +7 -0
  361. package/dist/test-topology/types.js.map +1 -0
  362. package/dist/unified-provider/compat/index.d.ts +11 -0
  363. package/dist/unified-provider/compat/index.d.ts.map +1 -0
  364. package/dist/unified-provider/compat/index.js +13 -0
  365. package/dist/unified-provider/compat/index.js.map +1 -0
  366. package/dist/unified-provider/compat/legacy-extractors.d.ts +63 -0
  367. package/dist/unified-provider/compat/legacy-extractors.d.ts.map +1 -0
  368. package/dist/unified-provider/compat/legacy-extractors.js +80 -0
  369. package/dist/unified-provider/compat/legacy-extractors.js.map +1 -0
  370. package/dist/unified-provider/compat/legacy-scanner.d.ts +28 -0
  371. package/dist/unified-provider/compat/legacy-scanner.d.ts.map +1 -0
  372. package/dist/unified-provider/compat/legacy-scanner.js +31 -0
  373. package/dist/unified-provider/compat/legacy-scanner.js.map +1 -0
  374. package/dist/unified-provider/index.d.ts +28 -0
  375. package/dist/unified-provider/index.d.ts.map +1 -0
  376. package/dist/unified-provider/index.js +47 -0
  377. package/dist/unified-provider/index.js.map +1 -0
  378. package/dist/unified-provider/integration/index.d.ts +9 -0
  379. package/dist/unified-provider/integration/index.d.ts.map +1 -0
  380. package/dist/unified-provider/integration/index.js +11 -0
  381. package/dist/unified-provider/integration/index.js.map +1 -0
  382. package/dist/unified-provider/integration/unified-data-access-adapter.d.ts +75 -0
  383. package/dist/unified-provider/integration/unified-data-access-adapter.d.ts.map +1 -0
  384. package/dist/unified-provider/integration/unified-data-access-adapter.js +210 -0
  385. package/dist/unified-provider/integration/unified-data-access-adapter.js.map +1 -0
  386. package/dist/unified-provider/integration/unified-scanner.d.ts +90 -0
  387. package/dist/unified-provider/integration/unified-scanner.d.ts.map +1 -0
  388. package/dist/unified-provider/integration/unified-scanner.js +369 -0
  389. package/dist/unified-provider/integration/unified-scanner.js.map +1 -0
  390. package/dist/unified-provider/matching/base-matcher.d.ts +80 -0
  391. package/dist/unified-provider/matching/base-matcher.d.ts.map +1 -0
  392. package/dist/unified-provider/matching/base-matcher.js +196 -0
  393. package/dist/unified-provider/matching/base-matcher.js.map +1 -0
  394. package/dist/unified-provider/matching/django-matcher.d.ts +32 -0
  395. package/dist/unified-provider/matching/django-matcher.d.ts.map +1 -0
  396. package/dist/unified-provider/matching/django-matcher.js +107 -0
  397. package/dist/unified-provider/matching/django-matcher.js.map +1 -0
  398. package/dist/unified-provider/matching/drizzle-matcher.d.ts +25 -0
  399. package/dist/unified-provider/matching/drizzle-matcher.d.ts.map +1 -0
  400. package/dist/unified-provider/matching/drizzle-matcher.js +123 -0
  401. package/dist/unified-provider/matching/drizzle-matcher.js.map +1 -0
  402. package/dist/unified-provider/matching/efcore-matcher.d.ts +27 -0
  403. package/dist/unified-provider/matching/efcore-matcher.d.ts.map +1 -0
  404. package/dist/unified-provider/matching/efcore-matcher.js +88 -0
  405. package/dist/unified-provider/matching/efcore-matcher.js.map +1 -0
  406. package/dist/unified-provider/matching/eloquent-matcher.d.ts +32 -0
  407. package/dist/unified-provider/matching/eloquent-matcher.d.ts.map +1 -0
  408. package/dist/unified-provider/matching/eloquent-matcher.js +162 -0
  409. package/dist/unified-provider/matching/eloquent-matcher.js.map +1 -0
  410. package/dist/unified-provider/matching/index.d.ts +19 -0
  411. package/dist/unified-provider/matching/index.d.ts.map +1 -0
  412. package/dist/unified-provider/matching/index.js +24 -0
  413. package/dist/unified-provider/matching/index.js.map +1 -0
  414. package/dist/unified-provider/matching/knex-matcher.d.ts +26 -0
  415. package/dist/unified-provider/matching/knex-matcher.d.ts.map +1 -0
  416. package/dist/unified-provider/matching/knex-matcher.js +109 -0
  417. package/dist/unified-provider/matching/knex-matcher.js.map +1 -0
  418. package/dist/unified-provider/matching/matcher-registry.d.ts +55 -0
  419. package/dist/unified-provider/matching/matcher-registry.d.ts.map +1 -0
  420. package/dist/unified-provider/matching/matcher-registry.js +130 -0
  421. package/dist/unified-provider/matching/matcher-registry.js.map +1 -0
  422. package/dist/unified-provider/matching/mongoose-matcher.d.ts +30 -0
  423. package/dist/unified-provider/matching/mongoose-matcher.d.ts.map +1 -0
  424. package/dist/unified-provider/matching/mongoose-matcher.js +132 -0
  425. package/dist/unified-provider/matching/mongoose-matcher.js.map +1 -0
  426. package/dist/unified-provider/matching/prisma-matcher.d.ts +31 -0
  427. package/dist/unified-provider/matching/prisma-matcher.d.ts.map +1 -0
  428. package/dist/unified-provider/matching/prisma-matcher.js +123 -0
  429. package/dist/unified-provider/matching/prisma-matcher.js.map +1 -0
  430. package/dist/unified-provider/matching/raw-sql-matcher.d.ts +31 -0
  431. package/dist/unified-provider/matching/raw-sql-matcher.d.ts.map +1 -0
  432. package/dist/unified-provider/matching/raw-sql-matcher.js +173 -0
  433. package/dist/unified-provider/matching/raw-sql-matcher.js.map +1 -0
  434. package/dist/unified-provider/matching/sequelize-matcher.d.ts +28 -0
  435. package/dist/unified-provider/matching/sequelize-matcher.d.ts.map +1 -0
  436. package/dist/unified-provider/matching/sequelize-matcher.js +132 -0
  437. package/dist/unified-provider/matching/sequelize-matcher.js.map +1 -0
  438. package/dist/unified-provider/matching/spring-data-matcher.d.ts +32 -0
  439. package/dist/unified-provider/matching/spring-data-matcher.d.ts.map +1 -0
  440. package/dist/unified-provider/matching/spring-data-matcher.js +112 -0
  441. package/dist/unified-provider/matching/spring-data-matcher.js.map +1 -0
  442. package/dist/unified-provider/matching/sqlalchemy-matcher.d.ts +32 -0
  443. package/dist/unified-provider/matching/sqlalchemy-matcher.d.ts.map +1 -0
  444. package/dist/unified-provider/matching/sqlalchemy-matcher.js +201 -0
  445. package/dist/unified-provider/matching/sqlalchemy-matcher.js.map +1 -0
  446. package/dist/unified-provider/matching/supabase-matcher.d.ts +27 -0
  447. package/dist/unified-provider/matching/supabase-matcher.d.ts.map +1 -0
  448. package/dist/unified-provider/matching/supabase-matcher.js +122 -0
  449. package/dist/unified-provider/matching/supabase-matcher.js.map +1 -0
  450. package/dist/unified-provider/matching/typeorm-matcher.d.ts +32 -0
  451. package/dist/unified-provider/matching/typeorm-matcher.d.ts.map +1 -0
  452. package/dist/unified-provider/matching/typeorm-matcher.js +169 -0
  453. package/dist/unified-provider/matching/typeorm-matcher.js.map +1 -0
  454. package/dist/unified-provider/migration/deprecated-extractors.d.ts +104 -0
  455. package/dist/unified-provider/migration/deprecated-extractors.d.ts.map +1 -0
  456. package/dist/unified-provider/migration/deprecated-extractors.js +129 -0
  457. package/dist/unified-provider/migration/deprecated-extractors.js.map +1 -0
  458. package/dist/unified-provider/migration/deprecated-scanner.d.ts +40 -0
  459. package/dist/unified-provider/migration/deprecated-scanner.d.ts.map +1 -0
  460. package/dist/unified-provider/migration/deprecated-scanner.js +49 -0
  461. package/dist/unified-provider/migration/deprecated-scanner.js.map +1 -0
  462. package/dist/unified-provider/migration/index.d.ts +41 -0
  463. package/dist/unified-provider/migration/index.d.ts.map +1 -0
  464. package/dist/unified-provider/migration/index.js +43 -0
  465. package/dist/unified-provider/migration/index.js.map +1 -0
  466. package/dist/unified-provider/normalization/base-normalizer.d.ts +188 -0
  467. package/dist/unified-provider/normalization/base-normalizer.d.ts.map +1 -0
  468. package/dist/unified-provider/normalization/base-normalizer.js +339 -0
  469. package/dist/unified-provider/normalization/base-normalizer.js.map +1 -0
  470. package/dist/unified-provider/normalization/csharp-normalizer.d.ts +58 -0
  471. package/dist/unified-provider/normalization/csharp-normalizer.d.ts.map +1 -0
  472. package/dist/unified-provider/normalization/csharp-normalizer.js +467 -0
  473. package/dist/unified-provider/normalization/csharp-normalizer.js.map +1 -0
  474. package/dist/unified-provider/normalization/index.d.ts +23 -0
  475. package/dist/unified-provider/normalization/index.d.ts.map +1 -0
  476. package/dist/unified-provider/normalization/index.js +62 -0
  477. package/dist/unified-provider/normalization/index.js.map +1 -0
  478. package/dist/unified-provider/normalization/java-normalizer.d.ts +54 -0
  479. package/dist/unified-provider/normalization/java-normalizer.d.ts.map +1 -0
  480. package/dist/unified-provider/normalization/java-normalizer.js +453 -0
  481. package/dist/unified-provider/normalization/java-normalizer.js.map +1 -0
  482. package/dist/unified-provider/normalization/php-normalizer.d.ts +54 -0
  483. package/dist/unified-provider/normalization/php-normalizer.d.ts.map +1 -0
  484. package/dist/unified-provider/normalization/php-normalizer.js +489 -0
  485. package/dist/unified-provider/normalization/php-normalizer.js.map +1 -0
  486. package/dist/unified-provider/normalization/python-normalizer.d.ts +61 -0
  487. package/dist/unified-provider/normalization/python-normalizer.d.ts.map +1 -0
  488. package/dist/unified-provider/normalization/python-normalizer.js +548 -0
  489. package/dist/unified-provider/normalization/python-normalizer.js.map +1 -0
  490. package/dist/unified-provider/normalization/typescript-normalizer.d.ts +60 -0
  491. package/dist/unified-provider/normalization/typescript-normalizer.d.ts.map +1 -0
  492. package/dist/unified-provider/normalization/typescript-normalizer.js +608 -0
  493. package/dist/unified-provider/normalization/typescript-normalizer.js.map +1 -0
  494. package/dist/unified-provider/parsing/index.d.ts +5 -0
  495. package/dist/unified-provider/parsing/index.d.ts.map +1 -0
  496. package/dist/unified-provider/parsing/index.js +5 -0
  497. package/dist/unified-provider/parsing/index.js.map +1 -0
  498. package/dist/unified-provider/parsing/parser-registry.d.ts +70 -0
  499. package/dist/unified-provider/parsing/parser-registry.d.ts.map +1 -0
  500. package/dist/unified-provider/parsing/parser-registry.js +260 -0
  501. package/dist/unified-provider/parsing/parser-registry.js.map +1 -0
  502. package/dist/unified-provider/provider/index.d.ts +5 -0
  503. package/dist/unified-provider/provider/index.d.ts.map +1 -0
  504. package/dist/unified-provider/provider/index.js +5 -0
  505. package/dist/unified-provider/provider/index.js.map +1 -0
  506. package/dist/unified-provider/provider/unified-language-provider.d.ts +56 -0
  507. package/dist/unified-provider/provider/unified-language-provider.d.ts.map +1 -0
  508. package/dist/unified-provider/provider/unified-language-provider.js +212 -0
  509. package/dist/unified-provider/provider/unified-language-provider.js.map +1 -0
  510. package/dist/unified-provider/types.d.ts +389 -0
  511. package/dist/unified-provider/types.d.ts.map +1 -0
  512. package/dist/unified-provider/types.js +9 -0
  513. package/dist/unified-provider/types.js.map +1 -0
  514. package/dist/wrappers/clustering/clusterer.d.ts +43 -0
  515. package/dist/wrappers/clustering/clusterer.d.ts.map +1 -0
  516. package/dist/wrappers/clustering/clusterer.js +374 -0
  517. package/dist/wrappers/clustering/clusterer.js.map +1 -0
  518. package/dist/wrappers/clustering/exclusions.d.ts +47 -0
  519. package/dist/wrappers/clustering/exclusions.d.ts.map +1 -0
  520. package/dist/wrappers/clustering/exclusions.js +318 -0
  521. package/dist/wrappers/clustering/exclusions.js.map +1 -0
  522. package/dist/wrappers/clustering/index.d.ts +6 -0
  523. package/dist/wrappers/clustering/index.d.ts.map +1 -0
  524. package/dist/wrappers/clustering/index.js +6 -0
  525. package/dist/wrappers/clustering/index.js.map +1 -0
  526. package/dist/wrappers/detection/detector.d.ts +69 -0
  527. package/dist/wrappers/detection/detector.d.ts.map +1 -0
  528. package/dist/wrappers/detection/detector.js +279 -0
  529. package/dist/wrappers/detection/detector.js.map +1 -0
  530. package/dist/wrappers/detection/index.d.ts +5 -0
  531. package/dist/wrappers/detection/index.d.ts.map +1 -0
  532. package/dist/wrappers/detection/index.js +5 -0
  533. package/dist/wrappers/detection/index.js.map +1 -0
  534. package/dist/wrappers/export/index.d.ts +5 -0
  535. package/dist/wrappers/export/index.d.ts.map +1 -0
  536. package/dist/wrappers/export/index.js +5 -0
  537. package/dist/wrappers/export/index.js.map +1 -0
  538. package/dist/wrappers/export/json.d.ts +127 -0
  539. package/dist/wrappers/export/json.d.ts.map +1 -0
  540. package/dist/wrappers/export/json.js +160 -0
  541. package/dist/wrappers/export/json.js.map +1 -0
  542. package/dist/wrappers/index.d.ts +56 -0
  543. package/dist/wrappers/index.d.ts.map +1 -0
  544. package/dist/wrappers/index.js +159 -0
  545. package/dist/wrappers/index.js.map +1 -0
  546. package/dist/wrappers/integration/adapter.d.ts +52 -0
  547. package/dist/wrappers/integration/adapter.d.ts.map +1 -0
  548. package/dist/wrappers/integration/adapter.js +209 -0
  549. package/dist/wrappers/integration/adapter.js.map +1 -0
  550. package/dist/wrappers/integration/index.d.ts +9 -0
  551. package/dist/wrappers/integration/index.d.ts.map +1 -0
  552. package/dist/wrappers/integration/index.js +12 -0
  553. package/dist/wrappers/integration/index.js.map +1 -0
  554. package/dist/wrappers/integration/pattern-adapter.d.ts +52 -0
  555. package/dist/wrappers/integration/pattern-adapter.d.ts.map +1 -0
  556. package/dist/wrappers/integration/pattern-adapter.js +192 -0
  557. package/dist/wrappers/integration/pattern-adapter.js.map +1 -0
  558. package/dist/wrappers/integration/scanner.d.ts +85 -0
  559. package/dist/wrappers/integration/scanner.d.ts.map +1 -0
  560. package/dist/wrappers/integration/scanner.js +367 -0
  561. package/dist/wrappers/integration/scanner.js.map +1 -0
  562. package/dist/wrappers/primitives/discovery.d.ts +57 -0
  563. package/dist/wrappers/primitives/discovery.d.ts.map +1 -0
  564. package/dist/wrappers/primitives/discovery.js +389 -0
  565. package/dist/wrappers/primitives/discovery.js.map +1 -0
  566. package/dist/wrappers/primitives/index.d.ts +6 -0
  567. package/dist/wrappers/primitives/index.d.ts.map +1 -0
  568. package/dist/wrappers/primitives/index.js +6 -0
  569. package/dist/wrappers/primitives/index.js.map +1 -0
  570. package/dist/wrappers/primitives/registry.d.ts +63 -0
  571. package/dist/wrappers/primitives/registry.d.ts.map +1 -0
  572. package/dist/wrappers/primitives/registry.js +447 -0
  573. package/dist/wrappers/primitives/registry.js.map +1 -0
  574. package/dist/wrappers/types.d.ts +137 -0
  575. package/dist/wrappers/types.d.ts.map +1 -0
  576. package/dist/wrappers/types.js +7 -0
  577. package/dist/wrappers/types.js.map +1 -0
  578. package/package.json +23 -18
@@ -11,7 +11,10 @@
11
11
  * - Traits
12
12
  * - Namespaces and use statements
13
13
  * - Arrow functions (fn =>)
14
- * - Closures
14
+ * - Closures (anonymous functions)
15
+ * - Nested functions within function bodies
16
+ * - Callback patterns (string callbacks, array callbacks, closures)
17
+ * - Module-level calls (top-level code)
15
18
  * - Laravel controller actions
16
19
  * - Static method calls (Class::method())
17
20
  */
@@ -36,6 +39,15 @@ export declare class PhpCallGraphExtractor extends BaseCallGraphExtractor {
36
39
  * Visit a tree-sitter node and extract information
37
40
  */
38
41
  private visitNode;
42
+ /**
43
+ * Extract calls at module level (not inside any function or class)
44
+ * This catches patterns like: require_once 'file.php'; $app->run();
45
+ */
46
+ private extractModuleLevelCalls;
47
+ /**
48
+ * Extract a call to an array (for module-level calls)
49
+ */
50
+ private extractCallToArray;
39
51
  /**
40
52
  * Extract namespace and visit children with namespace context
41
53
  */
@@ -56,6 +68,25 @@ export declare class PhpCallGraphExtractor extends BaseCallGraphExtractor {
56
68
  * Extract a function definition (not a method)
57
69
  */
58
70
  private extractFunctionDefinition;
71
+ /**
72
+ * Extract nested functions from a function body
73
+ * Handles: anonymous functions, arrow functions, and nested named functions
74
+ */
75
+ private extractNestedFunctions;
76
+ /**
77
+ * Extract an anonymous function (closure)
78
+ * e.g., $fn = function($x) use ($y) { return $x + $y; }
79
+ */
80
+ private extractAnonymousFunction;
81
+ /**
82
+ * Extract an arrow function
83
+ * e.g., $fn = fn($x) => $x * 2
84
+ */
85
+ private extractArrowFunction;
86
+ /**
87
+ * Extract calls recursively from an expression (for arrow functions)
88
+ */
89
+ private extractCallsFromBodyRecursive;
59
90
  /**
60
91
  * Extract a method declaration
61
92
  */
@@ -68,6 +99,22 @@ export declare class PhpCallGraphExtractor extends BaseCallGraphExtractor {
68
99
  * Extract a function call (global function)
69
100
  */
70
101
  private extractFunctionCall;
102
+ /**
103
+ * Extract callback references from function call arguments
104
+ * Handles patterns like:
105
+ * - String callbacks: array_map('strtoupper', $items)
106
+ * - Array callbacks: array_map([$this, 'process'], $items)
107
+ * - First-class callable: array_map($this->process(...), $items)
108
+ */
109
+ private extractCallbackReferences;
110
+ /**
111
+ * Check if a string value is a common non-callback string
112
+ */
113
+ private isCommonStringValue;
114
+ /**
115
+ * Extract callback from array syntax: [$object, 'method'] or [ClassName::class, 'method']
116
+ */
117
+ private extractArrayCallback;
71
118
  /**
72
119
  * Extract a member call ($obj->method())
73
120
  */
@@ -1 +1 @@
1
- {"version":3,"file":"php-extractor.d.ts","sourceRoot":"","sources":["../../../src/call-graph/extractors/php-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAOrB;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,sBAAsB;IAC/D,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAS;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAmE;IAEhG,OAAO,CAAC,MAAM,CAAiC;IAE/C;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,OAAO;IAI7B;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,oBAAoB;IA2B/D;;OAEG;IACH,OAAO,CAAC,SAAS;IA4DjB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAmE/B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAsDnC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA2C/B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAqDjC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA0DhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA2B7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiD3B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsCzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsCzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA+C7B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA6B5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAkBnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAQzB"}
1
+ {"version":3,"file":"php-extractor.d.ts","sourceRoot":"","sources":["../../../src/call-graph/extractors/php-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EAGrB,MAAM,aAAa,CAAC;AAOrB;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,sBAAsB;IAC/D,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAS;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAmE;IAEhG,OAAO,CAAC,MAAM,CAAiC;IAE/C;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,OAAO;IAI7B;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,oBAAoB;IA8B/D;;OAEG;IACH,OAAO,CAAC,SAAS;IA4DjB;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IA8D/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoI1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAmE/B;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAsDnC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA2C/B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA6DjC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA6C9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAqDhC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAmD5B;;OAEG;IACH,OAAO,CAAC,6BAA6B;IAoBrC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8DhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA2B7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAoD3B;;;;;;OAMG;IACH,OAAO,CAAC,yBAAyB;IAuDjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAsD5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsCzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAsCzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA+C7B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA6B5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAkBnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAQzB"}
@@ -11,7 +11,10 @@
11
11
  * - Traits
12
12
  * - Namespaces and use statements
13
13
  * - Arrow functions (fn =>)
14
- * - Closures
14
+ * - Closures (anonymous functions)
15
+ * - Nested functions within function bodies
16
+ * - Callback patterns (string callbacks, array callbacks, closures)
17
+ * - Module-level calls (top-level code)
15
18
  * - Laravel controller actions
16
19
  * - Static method calls (Class::method())
17
20
  */
@@ -47,6 +50,8 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
47
50
  // Extract namespace
48
51
  let currentNamespace = null;
49
52
  this.visitNode(tree.rootNode, result, source, null, currentNamespace);
53
+ // Extract module-level calls (top-level code not inside any function or class)
54
+ this.extractModuleLevelCalls(tree.rootNode, result, source);
50
55
  }
51
56
  catch (error) {
52
57
  result.errors.push(error instanceof Error ? error.message : 'Unknown parse error');
@@ -71,7 +76,7 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
71
76
  this.extractTraitDeclaration(node, result, source, currentNamespace);
72
77
  break;
73
78
  case 'function_definition':
74
- this.extractFunctionDefinition(node, result, source, currentNamespace);
79
+ this.extractFunctionDefinition(node, result, source, currentNamespace, null);
75
80
  break;
76
81
  case 'method_declaration':
77
82
  this.extractMethodDeclaration(node, result, source, currentClass, currentNamespace);
@@ -98,6 +103,186 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
98
103
  }
99
104
  }
100
105
  }
106
+ /**
107
+ * Extract calls at module level (not inside any function or class)
108
+ * This catches patterns like: require_once 'file.php'; $app->run();
109
+ */
110
+ extractModuleLevelCalls(rootNode, result, source) {
111
+ const moduleCalls = [];
112
+ const visit = (node) => {
113
+ // Skip function and class definitions
114
+ if (node.type === 'function_definition' ||
115
+ node.type === 'class_declaration' ||
116
+ node.type === 'interface_declaration' ||
117
+ node.type === 'trait_declaration' ||
118
+ node.type === 'namespace_definition') {
119
+ return;
120
+ }
121
+ // Extract calls from expression statements
122
+ if (node.type === 'function_call_expression' ||
123
+ node.type === 'member_call_expression' ||
124
+ node.type === 'scoped_call_expression' ||
125
+ node.type === 'object_creation_expression') {
126
+ this.extractCallToArray(node, moduleCalls, source);
127
+ }
128
+ for (const child of node.children) {
129
+ visit(child);
130
+ }
131
+ };
132
+ // Find the program node (root of PHP file)
133
+ const programNode = rootNode.children.find(c => c.type === 'program') ?? rootNode;
134
+ for (const child of programNode.children) {
135
+ visit(child);
136
+ }
137
+ // Add module-level calls to result
138
+ result.calls.push(...moduleCalls);
139
+ // If there are module-level calls, create a synthetic module function
140
+ if (moduleCalls.length > 0) {
141
+ const moduleFunc = this.createFunction({
142
+ name: '__module__',
143
+ startLine: 1,
144
+ endLine: rootNode.endPosition.row + 1,
145
+ startColumn: 0,
146
+ endColumn: 0,
147
+ parameters: [],
148
+ isMethod: false,
149
+ isStatic: false,
150
+ isExported: false,
151
+ isConstructor: false,
152
+ isAsync: false,
153
+ decorators: [],
154
+ bodyStartLine: 1,
155
+ bodyEndLine: rootNode.endPosition.row + 1,
156
+ });
157
+ result.functions.push(moduleFunc);
158
+ }
159
+ }
160
+ /**
161
+ * Extract a call to an array (for module-level calls)
162
+ */
163
+ extractCallToArray(node, calls, _source) {
164
+ if (node.type === 'function_call_expression') {
165
+ const funcNode = node.childForFieldName('function');
166
+ if (!funcNode)
167
+ return;
168
+ let calleeName;
169
+ let receiver;
170
+ if (funcNode.type === 'qualified_name') {
171
+ const parts = funcNode.text.split('\\').filter(p => p);
172
+ calleeName = parts.pop() ?? funcNode.text;
173
+ if (parts.length > 0) {
174
+ receiver = parts.join('\\');
175
+ }
176
+ }
177
+ else {
178
+ calleeName = funcNode.text;
179
+ }
180
+ const argsNode = node.childForFieldName('arguments');
181
+ let argumentCount = 0;
182
+ if (argsNode) {
183
+ for (const child of argsNode.children) {
184
+ if (child.type === 'argument') {
185
+ argumentCount++;
186
+ }
187
+ }
188
+ }
189
+ calls.push(this.createCall({
190
+ calleeName,
191
+ receiver,
192
+ fullExpression: node.text,
193
+ line: node.startPosition.row + 1,
194
+ column: node.startPosition.column,
195
+ argumentCount,
196
+ isMethodCall: false,
197
+ isConstructorCall: false,
198
+ }));
199
+ }
200
+ else if (node.type === 'member_call_expression') {
201
+ const nameNode = node.childForFieldName('name');
202
+ const objectNode = node.childForFieldName('object');
203
+ if (!nameNode)
204
+ return;
205
+ const argsNode = node.childForFieldName('arguments');
206
+ let argumentCount = 0;
207
+ if (argsNode) {
208
+ for (const child of argsNode.children) {
209
+ if (child.type === 'argument') {
210
+ argumentCount++;
211
+ }
212
+ }
213
+ }
214
+ calls.push(this.createCall({
215
+ calleeName: nameNode.text,
216
+ receiver: objectNode?.text,
217
+ fullExpression: node.text,
218
+ line: node.startPosition.row + 1,
219
+ column: node.startPosition.column,
220
+ argumentCount,
221
+ isMethodCall: true,
222
+ isConstructorCall: false,
223
+ }));
224
+ }
225
+ else if (node.type === 'scoped_call_expression') {
226
+ const nameNode = node.childForFieldName('name');
227
+ const scopeNode = node.childForFieldName('scope');
228
+ if (!nameNode)
229
+ return;
230
+ const argsNode = node.childForFieldName('arguments');
231
+ let argumentCount = 0;
232
+ if (argsNode) {
233
+ for (const child of argsNode.children) {
234
+ if (child.type === 'argument') {
235
+ argumentCount++;
236
+ }
237
+ }
238
+ }
239
+ calls.push(this.createCall({
240
+ calleeName: nameNode.text,
241
+ receiver: scopeNode?.text,
242
+ fullExpression: node.text,
243
+ line: node.startPosition.row + 1,
244
+ column: node.startPosition.column,
245
+ argumentCount,
246
+ isMethodCall: true,
247
+ isConstructorCall: false,
248
+ }));
249
+ }
250
+ else if (node.type === 'object_creation_expression') {
251
+ let calleeName;
252
+ let receiver;
253
+ for (const child of node.children) {
254
+ if (child.type === 'name' || child.type === 'qualified_name') {
255
+ const parts = child.text.split('\\').filter(p => p);
256
+ calleeName = parts.pop();
257
+ if (parts.length > 0) {
258
+ receiver = parts.join('\\');
259
+ }
260
+ break;
261
+ }
262
+ }
263
+ if (!calleeName)
264
+ return;
265
+ const argsNode = node.childForFieldName('arguments');
266
+ let argumentCount = 0;
267
+ if (argsNode) {
268
+ for (const child of argsNode.children) {
269
+ if (child.type === 'argument') {
270
+ argumentCount++;
271
+ }
272
+ }
273
+ }
274
+ calls.push(this.createCall({
275
+ calleeName,
276
+ receiver,
277
+ fullExpression: node.text,
278
+ line: node.startPosition.row + 1,
279
+ column: node.startPosition.column,
280
+ argumentCount,
281
+ isMethodCall: false,
282
+ isConstructorCall: true,
283
+ }));
284
+ }
285
+ }
101
286
  /**
102
287
  * Extract namespace and visit children with namespace context
103
288
  */
@@ -261,12 +446,16 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
261
446
  /**
262
447
  * Extract a function definition (not a method)
263
448
  */
264
- extractFunctionDefinition(node, result, source, currentNamespace) {
449
+ extractFunctionDefinition(node, result, source, currentNamespace, parentFunction) {
265
450
  const nameNode = node.childForFieldName('name');
266
451
  if (!nameNode)
267
452
  return;
268
453
  const name = nameNode.text;
269
- const qualifiedName = currentNamespace ? `${currentNamespace}\\${name}` : name;
454
+ let qualifiedName = currentNamespace ? `${currentNamespace}\\${name}` : name;
455
+ // Build qualified name including parent function for nested functions
456
+ if (parentFunction) {
457
+ qualifiedName = `${parentFunction}.${name}`;
458
+ }
270
459
  // Get return type
271
460
  const returnTypeNode = node.childForFieldName('return_type');
272
461
  const returnType = returnTypeNode?.text;
@@ -288,7 +477,7 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
288
477
  returnType,
289
478
  isMethod: false,
290
479
  isStatic: false,
291
- isExported: true, // PHP functions are always "exported" within their namespace
480
+ isExported: parentFunction ? false : true, // Nested functions are not exported
292
481
  isConstructor: false,
293
482
  isAsync: false,
294
483
  decorators,
@@ -299,6 +488,148 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
299
488
  // Extract calls from function body
300
489
  if (bodyNode) {
301
490
  this.extractCallsFromBody(bodyNode, result, source);
491
+ // Extract nested functions (closures, arrow functions, named functions)
492
+ this.extractNestedFunctions(bodyNode, result, source, currentNamespace, qualifiedName);
493
+ }
494
+ }
495
+ /**
496
+ * Extract nested functions from a function body
497
+ * Handles: anonymous functions, arrow functions, and nested named functions
498
+ */
499
+ extractNestedFunctions(bodyNode, result, source, currentNamespace, parentFunctionName) {
500
+ let closureCounter = 0;
501
+ const visit = (node) => {
502
+ // Named function inside another function (rare in PHP but possible)
503
+ if (node.type === 'function_definition') {
504
+ this.extractFunctionDefinition(node, result, source, currentNamespace, parentFunctionName);
505
+ return; // Don't recurse into this function's children
506
+ }
507
+ // Anonymous function: $fn = function($x) { ... }
508
+ if (node.type === 'anonymous_function_creation_expression') {
509
+ closureCounter++;
510
+ this.extractAnonymousFunction(node, result, source, parentFunctionName, closureCounter);
511
+ return;
512
+ }
513
+ // Arrow function: $fn = fn($x) => $x * 2
514
+ if (node.type === 'arrow_function') {
515
+ closureCounter++;
516
+ this.extractArrowFunction(node, result, source, parentFunctionName, closureCounter);
517
+ return;
518
+ }
519
+ // Don't recurse into class declarations
520
+ if (node.type === 'class_declaration') {
521
+ return;
522
+ }
523
+ for (const child of node.children) {
524
+ visit(child);
525
+ }
526
+ };
527
+ for (const child of bodyNode.children) {
528
+ visit(child);
529
+ }
530
+ }
531
+ /**
532
+ * Extract an anonymous function (closure)
533
+ * e.g., $fn = function($x) use ($y) { return $x + $y; }
534
+ */
535
+ extractAnonymousFunction(node, result, source, parentFunctionName, counter) {
536
+ const syntheticName = `closure${counter}`;
537
+ const qualifiedName = `${parentFunctionName}.${syntheticName}`;
538
+ // Get parameters
539
+ const parametersNode = node.childForFieldName('parameters');
540
+ const parameters = parametersNode ? this.extractParameters(parametersNode) : [];
541
+ // Get return type
542
+ const returnTypeNode = node.childForFieldName('return_type');
543
+ const returnType = returnTypeNode?.text;
544
+ // Check for static modifier
545
+ const isStatic = node.children.some(c => c.type === 'static_modifier');
546
+ // Get body
547
+ const bodyNode = node.childForFieldName('body');
548
+ const func = this.createFunction({
549
+ name: syntheticName,
550
+ qualifiedName,
551
+ startLine: node.startPosition.row + 1,
552
+ endLine: node.endPosition.row + 1,
553
+ startColumn: node.startPosition.column,
554
+ endColumn: node.endPosition.column,
555
+ parameters,
556
+ returnType,
557
+ isMethod: false,
558
+ isStatic,
559
+ isExported: false,
560
+ isConstructor: false,
561
+ isAsync: false,
562
+ decorators: [],
563
+ bodyStartLine: bodyNode ? bodyNode.startPosition.row + 1 : node.startPosition.row + 1,
564
+ bodyEndLine: bodyNode ? bodyNode.endPosition.row + 1 : node.endPosition.row + 1,
565
+ });
566
+ result.functions.push(func);
567
+ // Extract calls from closure body
568
+ if (bodyNode) {
569
+ this.extractCallsFromBody(bodyNode, result, source);
570
+ // Recursively extract nested functions
571
+ this.extractNestedFunctions(bodyNode, result, source, null, qualifiedName);
572
+ }
573
+ }
574
+ /**
575
+ * Extract an arrow function
576
+ * e.g., $fn = fn($x) => $x * 2
577
+ */
578
+ extractArrowFunction(node, result, source, parentFunctionName, counter) {
579
+ const syntheticName = `arrow${counter}`;
580
+ const qualifiedName = `${parentFunctionName}.${syntheticName}`;
581
+ // Get parameters
582
+ const parametersNode = node.childForFieldName('parameters');
583
+ const parameters = parametersNode ? this.extractParameters(parametersNode) : [];
584
+ // Get return type
585
+ const returnTypeNode = node.childForFieldName('return_type');
586
+ const returnType = returnTypeNode?.text;
587
+ // Check for static modifier
588
+ const isStatic = node.children.some(c => c.type === 'static_modifier');
589
+ // Get body (expression for arrow functions)
590
+ const bodyNode = node.childForFieldName('body');
591
+ const func = this.createFunction({
592
+ name: syntheticName,
593
+ qualifiedName,
594
+ startLine: node.startPosition.row + 1,
595
+ endLine: node.endPosition.row + 1,
596
+ startColumn: node.startPosition.column,
597
+ endColumn: node.endPosition.column,
598
+ parameters,
599
+ returnType,
600
+ isMethod: false,
601
+ isStatic,
602
+ isExported: false,
603
+ isConstructor: false,
604
+ isAsync: false,
605
+ decorators: [],
606
+ bodyStartLine: bodyNode ? bodyNode.startPosition.row + 1 : node.startPosition.row + 1,
607
+ bodyEndLine: bodyNode ? bodyNode.endPosition.row + 1 : node.endPosition.row + 1,
608
+ });
609
+ result.functions.push(func);
610
+ // Extract calls from arrow function body
611
+ if (bodyNode) {
612
+ this.extractCallsFromBodyRecursive(bodyNode, result, source);
613
+ }
614
+ }
615
+ /**
616
+ * Extract calls recursively from an expression (for arrow functions)
617
+ */
618
+ extractCallsFromBodyRecursive(node, result, source) {
619
+ if (node.type === 'function_call_expression') {
620
+ this.extractFunctionCall(node, result, source);
621
+ }
622
+ else if (node.type === 'member_call_expression') {
623
+ this.extractMemberCall(node, result, source);
624
+ }
625
+ else if (node.type === 'scoped_call_expression') {
626
+ this.extractScopedCall(node, result, source);
627
+ }
628
+ else if (node.type === 'object_creation_expression') {
629
+ this.extractObjectCreation(node, result, source);
630
+ }
631
+ for (const child of node.children) {
632
+ this.extractCallsFromBodyRecursive(child, result, source);
302
633
  }
303
634
  }
304
635
  /**
@@ -323,9 +654,10 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
323
654
  const decorators = this.extractAttributes(node);
324
655
  // Get body
325
656
  const bodyNode = node.childForFieldName('body');
657
+ const qualifiedName = currentClass ? `${currentClass}.${isConstructor ? 'constructor' : name}` : name;
326
658
  const func = this.createFunction({
327
659
  name: isConstructor ? 'constructor' : (isDestructor ? 'destructor' : name),
328
- qualifiedName: currentClass ? `${currentClass}.${isConstructor ? 'constructor' : name}` : name,
660
+ qualifiedName,
329
661
  startLine: node.startPosition.row + 1,
330
662
  endLine: node.endPosition.row + 1,
331
663
  startColumn: node.startPosition.column,
@@ -346,6 +678,8 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
346
678
  // Extract calls from method body
347
679
  if (bodyNode) {
348
680
  this.extractCallsFromBody(bodyNode, result, source);
681
+ // Extract nested functions (closures, arrow functions)
682
+ this.extractNestedFunctions(bodyNode, result, source, null, qualifiedName);
349
683
  }
350
684
  }
351
685
  /**
@@ -414,6 +748,126 @@ export class PhpCallGraphExtractor extends BaseCallGraphExtractor {
414
748
  isConstructorCall: false,
415
749
  });
416
750
  result.calls.push(call);
751
+ // Extract callback references from arguments
752
+ this.extractCallbackReferences(node, result);
753
+ }
754
+ /**
755
+ * Extract callback references from function call arguments
756
+ * Handles patterns like:
757
+ * - String callbacks: array_map('strtoupper', $items)
758
+ * - Array callbacks: array_map([$this, 'process'], $items)
759
+ * - First-class callable: array_map($this->process(...), $items)
760
+ */
761
+ extractCallbackReferences(node, result) {
762
+ const argsNode = node.childForFieldName('arguments');
763
+ if (!argsNode)
764
+ return;
765
+ for (const arg of argsNode.children) {
766
+ if (arg.type !== 'argument')
767
+ continue;
768
+ const argExpr = arg.namedChildren[0];
769
+ if (!argExpr)
770
+ continue;
771
+ // String callback: 'functionName' or "functionName"
772
+ if (argExpr.type === 'string' || argExpr.type === 'encapsed_string') {
773
+ const funcName = argExpr.text.replace(/^['"]|['"]$/g, '');
774
+ // Only treat as callback if it looks like a valid function name
775
+ if (/^[a-z_][a-z0-9_]*$/i.test(funcName) && !this.isCommonStringValue(funcName)) {
776
+ result.calls.push(this.createCall({
777
+ calleeName: funcName,
778
+ fullExpression: funcName,
779
+ line: argExpr.startPosition.row + 1,
780
+ column: argExpr.startPosition.column,
781
+ argumentCount: 0,
782
+ isMethodCall: false,
783
+ isConstructorCall: false,
784
+ }));
785
+ }
786
+ }
787
+ // Array callback: [$object, 'methodName'] or [ClassName::class, 'methodName']
788
+ if (argExpr.type === 'array_creation_expression') {
789
+ this.extractArrayCallback(argExpr, result);
790
+ }
791
+ // Variable that might be a callable: $callback
792
+ if (argExpr.type === 'variable_name') {
793
+ const varName = argExpr.text.replace(/^\$/, '');
794
+ // Common callback variable names
795
+ const callbackVarNames = ['callback', 'handler', 'fn', 'func', 'callable', 'closure'];
796
+ if (callbackVarNames.some(n => varName.toLowerCase().includes(n))) {
797
+ result.calls.push(this.createCall({
798
+ calleeName: varName,
799
+ fullExpression: argExpr.text,
800
+ line: argExpr.startPosition.row + 1,
801
+ column: argExpr.startPosition.column,
802
+ argumentCount: 0,
803
+ isMethodCall: false,
804
+ isConstructorCall: false,
805
+ }));
806
+ }
807
+ }
808
+ }
809
+ }
810
+ /**
811
+ * Check if a string value is a common non-callback string
812
+ */
813
+ isCommonStringValue(value) {
814
+ const commonValues = [
815
+ 'true', 'false', 'null', 'yes', 'no', 'on', 'off',
816
+ 'asc', 'desc', 'id', 'name', 'email', 'password',
817
+ 'get', 'post', 'put', 'delete', 'patch',
818
+ ];
819
+ return commonValues.includes(value.toLowerCase());
820
+ }
821
+ /**
822
+ * Extract callback from array syntax: [$object, 'method'] or [ClassName::class, 'method']
823
+ */
824
+ extractArrayCallback(node, result) {
825
+ const elements = [];
826
+ for (const child of node.children) {
827
+ if (child.type === 'array_element_initializer') {
828
+ const valueNode = child.namedChildren[0];
829
+ if (valueNode) {
830
+ elements.push(valueNode);
831
+ }
832
+ }
833
+ }
834
+ // Need exactly 2 elements: [object/class, method]
835
+ if (elements.length !== 2)
836
+ return;
837
+ const [first, second] = elements;
838
+ if (!first || !second)
839
+ return;
840
+ // Second element should be a string (method name)
841
+ if (second.type !== 'string' && second.type !== 'encapsed_string')
842
+ return;
843
+ const methodName = second.text.replace(/^['"]|['"]$/g, '');
844
+ let receiver;
845
+ // First element: $this, $object, ClassName::class, or 'ClassName'
846
+ if (first.type === 'variable_name') {
847
+ receiver = first.text;
848
+ }
849
+ else if (first.type === 'class_constant_access_expression') {
850
+ // ClassName::class
851
+ const classNode = first.childForFieldName('class');
852
+ if (classNode) {
853
+ receiver = classNode.text;
854
+ }
855
+ }
856
+ else if (first.type === 'string' || first.type === 'encapsed_string') {
857
+ receiver = first.text.replace(/^['"]|['"]$/g, '');
858
+ }
859
+ if (methodName) {
860
+ result.calls.push(this.createCall({
861
+ calleeName: methodName,
862
+ receiver,
863
+ fullExpression: node.text,
864
+ line: node.startPosition.row + 1,
865
+ column: node.startPosition.column,
866
+ argumentCount: 0,
867
+ isMethodCall: true,
868
+ isConstructorCall: false,
869
+ }));
870
+ }
417
871
  }
418
872
  /**
419
873
  * Extract a member call ($obj->method())