pyflow-analysis 0.1.0__py3-none-any.whl

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 (757) hide show
  1. pyflow/__init__.py +22 -0
  2. pyflow/_pyflow.py +50 -0
  3. pyflow/analysis/__init__.py +14 -0
  4. pyflow/analysis/alias/__init__.py +3 -0
  5. pyflow/analysis/alias/flow_sensitive/__init__.py +148 -0
  6. pyflow/analysis/alias/flow_sensitive/_transfer_calls.py +3493 -0
  7. pyflow/analysis/alias/flow_sensitive/_transfer_ops.py +1969 -0
  8. pyflow/analysis/alias/flow_sensitive/abstraction.py +1632 -0
  9. pyflow/analysis/alias/flow_sensitive/heap_analysis.py +280 -0
  10. pyflow/analysis/alias/flow_sensitive/heap_effects.py +1209 -0
  11. pyflow/analysis/alias/flow_sensitive/heap_state.py +381 -0
  12. pyflow/analysis/alias/flow_sensitive/heap_summary.py +299 -0
  13. pyflow/analysis/alias/flow_sensitive/intrinsics.py +948 -0
  14. pyflow/analysis/alias/flow_sensitive/model.py +449 -0
  15. pyflow/analysis/alias/flow_sensitive/points_to_graph.py +722 -0
  16. pyflow/analysis/alias/flow_sensitive/transfer.py +1483 -0
  17. pyflow/analysis/alias/kcfa/__init__.py +33 -0
  18. pyflow/analysis/alias/kcfa/_pythonstan/__init__.py +2 -0
  19. pyflow/analysis/alias/kcfa/_pythonstan/analysis/__init__.py +1 -0
  20. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/__init__.py +53 -0
  21. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/logging.py +490 -0
  22. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/operation.py +1601 -0
  23. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/pointer_adapter.py +353 -0
  24. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/solver.py +559 -0
  25. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/state.py +701 -0
  26. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/value.py +804 -0
  27. pyflow/analysis/alias/kcfa/_pythonstan/analysis/analysis.py +86 -0
  28. pyflow/analysis/alias/kcfa/_pythonstan/analysis/class_hierarchy.py +83 -0
  29. pyflow/analysis/alias/kcfa/_pythonstan/analysis/closure.py +69 -0
  30. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/__init__.py +4 -0
  31. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/analysis.py +58 -0
  32. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/driver.py +38 -0
  33. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/liveness.py +33 -0
  34. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/reaching_definition.py +52 -0
  35. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/solver.py +178 -0
  36. pyflow/analysis/alias/kcfa/_pythonstan/analysis/defuse.py +46 -0
  37. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/__init__.py +18 -0
  38. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/__init__.py +110 -0
  39. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/analysis.py +382 -0
  40. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/builtin_api_handler.py +1872 -0
  41. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/call_graph_analyzer.py +289 -0
  42. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/class_hierarchy.py +304 -0
  43. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/config.py +139 -0
  44. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/constraints.py +576 -0
  45. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/context.py +496 -0
  46. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/context_selector.py +297 -0
  47. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/debug_monitor.py +34 -0
  48. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/heap_model.py +221 -0
  49. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/ir_translator.py +1181 -0
  50. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/libs/__init__.py +2 -0
  51. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/libs/math.py +244 -0
  52. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/module_analysis.py +269 -0
  53. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/module_summary.py +191 -0
  54. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/object.py +685 -0
  55. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/pointer_flow_graph.py +282 -0
  56. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/points_to_set.py +301 -0
  57. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/__init__.py +21 -0
  58. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/attribute_semantics.py +512 -0
  59. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/compose_processor.py +46 -0
  60. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/container.py +128 -0
  61. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/generator.py +353 -0
  62. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/normal_call.py +664 -0
  63. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/processor.py +36 -0
  64. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/super_resolve.py +131 -0
  65. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/pta_query_adapter.py +329 -0
  66. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/solver.py +917 -0
  67. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/solver_interface.py +76 -0
  68. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/state.py +735 -0
  69. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/unknown_tracker.py +126 -0
  70. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/variable.py +144 -0
  71. pyflow/analysis/alias/kcfa/_pythonstan/analysis/scope/__init__.py +2 -0
  72. pyflow/analysis/alias/kcfa/_pythonstan/analysis/scope/analysis.py +37 -0
  73. pyflow/analysis/alias/kcfa/_pythonstan/analysis/scope/closure.py +81 -0
  74. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/__init__.py +8 -0
  75. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/block_cfg.py +133 -0
  76. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/cfg.py +95 -0
  77. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/driver.py +26 -0
  78. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/__init__.py +0 -0
  79. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/base.py +112 -0
  80. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/baseprocess.py +524 -0
  81. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/icfg.py +0 -0
  82. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/icfg_pre_transform.py +69 -0
  83. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/icfg_transform.py +0 -0
  84. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/postprocessor.py +308 -0
  85. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/preprocessor.py +375 -0
  86. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/ir.py +361 -0
  87. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/three_address.py +1161 -0
  88. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/transform.py +27 -0
  89. pyflow/analysis/alias/kcfa/_pythonstan/graph/__init__.py +0 -0
  90. pyflow/analysis/alias/kcfa/_pythonstan/graph/call_graph/__init__.py +2 -0
  91. pyflow/analysis/alias/kcfa/_pythonstan/graph/call_graph/call_edge.py +45 -0
  92. pyflow/analysis/alias/kcfa/_pythonstan/graph/call_graph/call_graph.py +77 -0
  93. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/__init__.py +3 -0
  94. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/base_block.py +83 -0
  95. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/cfg.py +200 -0
  96. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/dump.py +20 -0
  97. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/edges.py +162 -0
  98. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/visualize.py +112 -0
  99. pyflow/analysis/alias/kcfa/_pythonstan/graph/dominator_tree.py +126 -0
  100. pyflow/analysis/alias/kcfa/_pythonstan/graph/graph.py +81 -0
  101. pyflow/analysis/alias/kcfa/_pythonstan/graph/icfg/__init__.py +0 -0
  102. pyflow/analysis/alias/kcfa/_pythonstan/graph/icfg/icfg.py +98 -0
  103. pyflow/analysis/alias/kcfa/_pythonstan/ir/__init__.py +2 -0
  104. pyflow/analysis/alias/kcfa/_pythonstan/ir/ir_statements.py +1579 -0
  105. pyflow/analysis/alias/kcfa/_pythonstan/ir/ir_visitor.py +21 -0
  106. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/LICENSE.pythonstan +28 -0
  107. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/README.md +99 -0
  108. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/abc.cpython-313.pyc +0 -0
  109. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/base64.cpython-313.pyc +0 -0
  110. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/bisect.cpython-313.pyc +0 -0
  111. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/collections.cpython-313.pyc +0 -0
  112. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/contextlib.cpython-313.pyc +0 -0
  113. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/copy.cpython-313.pyc +0 -0
  114. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/csv.cpython-313.pyc +0 -0
  115. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/dataclasses.cpython-313.pyc +0 -0
  116. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/datetime.cpython-313.pyc +0 -0
  117. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/email.cpython-313.pyc +0 -0
  118. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/enum.cpython-313.pyc +0 -0
  119. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/fnmatch.cpython-313.pyc +0 -0
  120. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/functools.cpython-313.pyc +0 -0
  121. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/glob.cpython-313.pyc +0 -0
  122. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/hashlib.cpython-313.pyc +0 -0
  123. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/heapq.cpython-313.pyc +0 -0
  124. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/hmac.cpython-313.pyc +0 -0
  125. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/http.cpython-313.pyc +0 -0
  126. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/importlib.cpython-313.pyc +0 -0
  127. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/inspect.cpython-313.pyc +0 -0
  128. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/io.cpython-313.pyc +0 -0
  129. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/itertools.cpython-313.pyc +0 -0
  130. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/json.cpython-313.pyc +0 -0
  131. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/logging.cpython-313.pyc +0 -0
  132. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/math.cpython-313.pyc +0 -0
  133. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/mimetypes.cpython-313.pyc +0 -0
  134. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/operator.cpython-313.pyc +0 -0
  135. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/os.cpython-313.pyc +0 -0
  136. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/pathlib.cpython-313.pyc +0 -0
  137. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/pickle.cpython-313.pyc +0 -0
  138. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/random.cpython-313.pyc +0 -0
  139. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/re.cpython-313.pyc +0 -0
  140. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/secrets.cpython-313.pyc +0 -0
  141. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/shutil.cpython-313.pyc +0 -0
  142. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/somelib.cpython-313.pyc +0 -0
  143. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/tempfile.cpython-313.pyc +0 -0
  144. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/time.cpython-313.pyc +0 -0
  145. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/traceback.cpython-313.pyc +0 -0
  146. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/types.cpython-313.pyc +0 -0
  147. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/uuid.cpython-313.pyc +0 -0
  148. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/warnings.cpython-313.pyc +0 -0
  149. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/weakref.cpython-313.pyc +0 -0
  150. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/abc.py +80 -0
  151. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/base64.py +62 -0
  152. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/bisect.py +52 -0
  153. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/collections.py +187 -0
  154. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/contextlib.py +113 -0
  155. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/copy.py +15 -0
  156. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/csv.py +163 -0
  157. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/dataclasses.py +150 -0
  158. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/datetime.py +171 -0
  159. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/email.py +270 -0
  160. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/enum.py +144 -0
  161. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/fnmatch.py +14 -0
  162. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/functools.py +84 -0
  163. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/glob.py +10 -0
  164. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/hashlib.py +74 -0
  165. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/heapq.py +91 -0
  166. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/hmac.py +31 -0
  167. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/http.py +317 -0
  168. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/importlib.py +126 -0
  169. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/inspect.py +246 -0
  170. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/io.py +471 -0
  171. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/itertools.py +164 -0
  172. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/json.py +80 -0
  173. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/logging.py +193 -0
  174. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/math.py +244 -0
  175. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/mimetypes.py +119 -0
  176. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/operator.py +310 -0
  177. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/os.py +286 -0
  178. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/pathlib.py +196 -0
  179. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/pickle.py +153 -0
  180. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/random.py +125 -0
  181. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/re.py +125 -0
  182. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/secrets.py +29 -0
  183. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/shutil.py +99 -0
  184. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/somelib.py +2 -0
  185. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/tempfile.py +76 -0
  186. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/time.py +65 -0
  187. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/traceback.py +151 -0
  188. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/types.py +247 -0
  189. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/__init__.py +1 -0
  190. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/__pycache__/__init__.cpython-313.pyc +0 -0
  191. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/__pycache__/parse.cpython-313.pyc +0 -0
  192. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/parse.py +221 -0
  193. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/uuid.py +34 -0
  194. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/warnings.py +82 -0
  195. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/weakref.py +272 -0
  196. pyflow/analysis/alias/kcfa/_pythonstan/utils/__init__.py +1 -0
  197. pyflow/analysis/alias/kcfa/_pythonstan/utils/ast_rename.py +35 -0
  198. pyflow/analysis/alias/kcfa/_pythonstan/utils/common.py +70 -0
  199. pyflow/analysis/alias/kcfa/_pythonstan/utils/persistent_rb_tree.py +364 -0
  200. pyflow/analysis/alias/kcfa/_pythonstan/utils/temp_var_generator.py +68 -0
  201. pyflow/analysis/alias/kcfa/_pythonstan/utils/toposort.py +63 -0
  202. pyflow/analysis/alias/kcfa/_pythonstan/utils/var_collector.py +72 -0
  203. pyflow/analysis/alias/kcfa/_pythonstan/world/__init__.py +1 -0
  204. pyflow/analysis/alias/kcfa/_pythonstan/world/analysis_manager.py +141 -0
  205. pyflow/analysis/alias/kcfa/_pythonstan/world/class_hierarchy.py +56 -0
  206. pyflow/analysis/alias/kcfa/_pythonstan/world/config.py +93 -0
  207. pyflow/analysis/alias/kcfa/_pythonstan/world/import_manager.py +16 -0
  208. pyflow/analysis/alias/kcfa/_pythonstan/world/namespace.py +327 -0
  209. pyflow/analysis/alias/kcfa/_pythonstan/world/pipeline.py +153 -0
  210. pyflow/analysis/alias/kcfa/_pythonstan/world/scope_manager.py +133 -0
  211. pyflow/analysis/alias/kcfa/_pythonstan/world/world.py +49 -0
  212. pyflow/analysis/alias/kcfa/bridge.py +136 -0
  213. pyflow/analysis/astcollector.py +171 -0
  214. pyflow/analysis/cache/incremental.py +226 -0
  215. pyflow/analysis/callgraph/__init__.py +58 -0
  216. pyflow/analysis/callgraph/ast_based.py +184 -0
  217. pyflow/analysis/callgraph/callgraph.py +86 -0
  218. pyflow/analysis/callgraph/constraint_based/__init__.py +26 -0
  219. pyflow/analysis/callgraph/constraint_based/_analyzer.py +1976 -0
  220. pyflow/analysis/callgraph/constraint_based/_collector.py +704 -0
  221. pyflow/analysis/callgraph/constraint_based/_evaluator.py +984 -0
  222. pyflow/analysis/callgraph/constraint_based/_loader.py +115 -0
  223. pyflow/analysis/callgraph/constraint_based/_resolver.py +2852 -0
  224. pyflow/analysis/callgraph/constraint_based/api.py +233 -0
  225. pyflow/analysis/callgraph/constraint_based/engine.py +717 -0
  226. pyflow/analysis/callgraph/constraint_based/model.py +303 -0
  227. pyflow/analysis/callgraph/formats.py +99 -0
  228. pyflow/analysis/callgraph/pycg_based.py +273 -0
  229. pyflow/analysis/cdg/__init__.py +52 -0
  230. pyflow/analysis/cdg/construction.py +256 -0
  231. pyflow/analysis/cdg/dump.py +415 -0
  232. pyflow/analysis/cdg/graph.py +456 -0
  233. pyflow/analysis/cfg/__init__.py +38 -0
  234. pyflow/analysis/cfg/dfs.py +55 -0
  235. pyflow/analysis/cfg/dom.py +243 -0
  236. pyflow/analysis/cfg/dump.py +322 -0
  237. pyflow/analysis/cfg/expandphi.py +113 -0
  238. pyflow/analysis/cfg/gc.py +93 -0
  239. pyflow/analysis/cfg/graph.py +878 -0
  240. pyflow/analysis/cfg/inline.py +337 -0
  241. pyflow/analysis/cfg/killflow.py +360 -0
  242. pyflow/analysis/cfg/optimize.py +164 -0
  243. pyflow/analysis/cfg/simplify.py +19 -0
  244. pyflow/analysis/cfg/ssa.py +693 -0
  245. pyflow/analysis/cfg/ssatransform.py +13 -0
  246. pyflow/analysis/cfg/structuralanalysis.py +422 -0
  247. pyflow/analysis/cfg/transform.py +527 -0
  248. pyflow/analysis/cpa/__init__.py +657 -0
  249. pyflow/analysis/cpa/base.py +430 -0
  250. pyflow/analysis/cpa/codecloner.py +262 -0
  251. pyflow/analysis/cpa/constraintextractor.py +797 -0
  252. pyflow/analysis/cpa/constraints.py +1071 -0
  253. pyflow/analysis/cpa/simpleimagebuilder.py +299 -0
  254. pyflow/analysis/cpasignature.py +132 -0
  255. pyflow/analysis/cpg/__init__.py +93 -0
  256. pyflow/analysis/cpg/build.py +221 -0
  257. pyflow/analysis/cpg/dump.py +102 -0
  258. pyflow/analysis/cpg/graph.py +1877 -0
  259. pyflow/analysis/cpg/persist.py +346 -0
  260. pyflow/analysis/cpg/profiles.py +286 -0
  261. pyflow/analysis/cpg/rules.py +365 -0
  262. pyflow/analysis/cpg/taint.py +1934 -0
  263. pyflow/analysis/dataflowIR/__init__.py +6 -0
  264. pyflow/analysis/dataflowIR/annotations.py +174 -0
  265. pyflow/analysis/dataflowIR/convert.py +795 -0
  266. pyflow/analysis/dataflowIR/dump.py +443 -0
  267. pyflow/analysis/dataflowIR/graph.py +1648 -0
  268. pyflow/analysis/dataflowIR/ordering.py +134 -0
  269. pyflow/analysis/dataflowIR/predicate.py +233 -0
  270. pyflow/analysis/dataflowIR/transform/__init__.py +15 -0
  271. pyflow/analysis/dataflowIR/transform/dce.py +215 -0
  272. pyflow/analysis/dataflowIR/transform/loadelimination.py +185 -0
  273. pyflow/analysis/dataflowIR/traverse.py +91 -0
  274. pyflow/analysis/ddg/__init__.py +53 -0
  275. pyflow/analysis/ddg/construction.py +310 -0
  276. pyflow/analysis/ddg/dump.py +218 -0
  277. pyflow/analysis/ddg/graph.py +295 -0
  278. pyflow/analysis/dump/__init__.py +15 -0
  279. pyflow/analysis/dump/dumpgraphs.py +93 -0
  280. pyflow/analysis/dump/dumpreport.py +841 -0
  281. pyflow/analysis/dump/dumputil.py +98 -0
  282. pyflow/analysis/fsdf/__init__.py +1107 -0
  283. pyflow/analysis/fsdf/canonicalset.py +176 -0
  284. pyflow/analysis/fsdf/canonicaltree.py +1071 -0
  285. pyflow/analysis/ifds/__init__.py +284 -0
  286. pyflow/analysis/ifds/annotation_fallback.py +21 -0
  287. pyflow/analysis/ifds/annotation_synthesis.py +803 -0
  288. pyflow/analysis/ifds/api.py +567 -0
  289. pyflow/analysis/ifds/backward_solver.py +328 -0
  290. pyflow/analysis/ifds/cfg_adapter.py +1575 -0
  291. pyflow/analysis/ifds/clients/_call_model.py +166 -0
  292. pyflow/analysis/ifds/clients/_client_common.py +1617 -0
  293. pyflow/analysis/ifds/clients/flow_path_collector.py +159 -0
  294. pyflow/analysis/ifds/clients/library_presets.py +1134 -0
  295. pyflow/analysis/ifds/clients/nullness.py +754 -0
  296. pyflow/analysis/ifds/clients/registry/__init__.py +26 -0
  297. pyflow/analysis/ifds/clients/registry/loader.py +688 -0
  298. pyflow/analysis/ifds/clients/registry/validate.py +37 -0
  299. pyflow/analysis/ifds/clients/taint.py +782 -0
  300. pyflow/analysis/ifds/clients/typestate.py +1550 -0
  301. pyflow/analysis/ifds/clients/typestate_engine.py +534 -0
  302. pyflow/analysis/ifds/diagnostics.py +29 -0
  303. pyflow/analysis/ifds/preparation.py +97 -0
  304. pyflow/analysis/ifds/problem.py +363 -0
  305. pyflow/analysis/ifds/queries.py +142 -0
  306. pyflow/analysis/ifds/reporting.py +289 -0
  307. pyflow/analysis/ifds/shadow_scan.py +349 -0
  308. pyflow/analysis/ifds/solver.py +1495 -0
  309. pyflow/analysis/ifds/supergraph.py +186 -0
  310. pyflow/analysis/ifds/transfers.py +187 -0
  311. pyflow/analysis/ipa/__init__.py +77 -0
  312. pyflow/analysis/ipa/calling/__init__.py +17 -0
  313. pyflow/analysis/ipa/calling/callbinder.py +93 -0
  314. pyflow/analysis/ipa/calling/cpa.py +197 -0
  315. pyflow/analysis/ipa/calling/transfer.py +208 -0
  316. pyflow/analysis/ipa/constraintextractor.py +804 -0
  317. pyflow/analysis/ipa/constraints/__init__.py +18 -0
  318. pyflow/analysis/ipa/constraints/base.py +66 -0
  319. pyflow/analysis/ipa/constraints/calls.py +424 -0
  320. pyflow/analysis/ipa/constraints/flow.py +445 -0
  321. pyflow/analysis/ipa/constraints/node.py +299 -0
  322. pyflow/analysis/ipa/constraints/qualifiers.py +17 -0
  323. pyflow/analysis/ipa/constraints/split.py +178 -0
  324. pyflow/analysis/ipa/dump.py +246 -0
  325. pyflow/analysis/ipa/entrypointbuilder.py +52 -0
  326. pyflow/analysis/ipa/escape/__init__.py +19 -0
  327. pyflow/analysis/ipa/escape/objectescape.py +77 -0
  328. pyflow/analysis/ipa/ipanalysis.py +319 -0
  329. pyflow/analysis/ipa/memory/__init__.py +16 -0
  330. pyflow/analysis/ipa/memory/extractorpolicy.py +38 -0
  331. pyflow/analysis/ipa/memory/storegraphpolicy.py +17 -0
  332. pyflow/analysis/ipa/model/__init__.py +18 -0
  333. pyflow/analysis/ipa/model/context.py +277 -0
  334. pyflow/analysis/ipa/model/invocation.py +159 -0
  335. pyflow/analysis/ipa/model/object.py +102 -0
  336. pyflow/analysis/ipa/model/objectname.py +77 -0
  337. pyflow/analysis/ipa/model/region.py +51 -0
  338. pyflow/analysis/ipa/summary/__init__.py +120 -0
  339. pyflow/analysis/ir_utils.py +215 -0
  340. pyflow/analysis/lifetimeanalysis/__init__.py +935 -0
  341. pyflow/analysis/lifetimeanalysis/database/__init__.py +17 -0
  342. pyflow/analysis/lifetimeanalysis/database/base.py +72 -0
  343. pyflow/analysis/lifetimeanalysis/database/lattice.py +189 -0
  344. pyflow/analysis/lifetimeanalysis/database/mapping.py +174 -0
  345. pyflow/analysis/lifetimeanalysis/database/structure.py +224 -0
  346. pyflow/analysis/lifetimeanalysis/database/tupleset.py +141 -0
  347. pyflow/analysis/numbering/__init__.py +17 -0
  348. pyflow/analysis/numbering/dataflow.py +214 -0
  349. pyflow/analysis/numbering/dominance.py +120 -0
  350. pyflow/analysis/numbering/readmodify.py +251 -0
  351. pyflow/analysis/numbering/ssa.py +604 -0
  352. pyflow/analysis/pdg/__init__.py +55 -0
  353. pyflow/analysis/pdg/construction.py +447 -0
  354. pyflow/analysis/pdg/cypher.py +1150 -0
  355. pyflow/analysis/pdg/dump.py +129 -0
  356. pyflow/analysis/pdg/graph.py +308 -0
  357. pyflow/analysis/programculler.py +224 -0
  358. pyflow/analysis/shape/__init__.py +466 -0
  359. pyflow/analysis/shape/constraintbuilder.py +933 -0
  360. pyflow/analysis/shape/constraints.py +510 -0
  361. pyflow/analysis/shape/dataflow.py +202 -0
  362. pyflow/analysis/shape/model/__init__.py +27 -0
  363. pyflow/analysis/shape/model/canonical.py +137 -0
  364. pyflow/analysis/shape/model/configuration.py +78 -0
  365. pyflow/analysis/shape/model/expressions.py +268 -0
  366. pyflow/analysis/shape/model/pathinformation.py +645 -0
  367. pyflow/analysis/shape/model/referencecount.py +212 -0
  368. pyflow/analysis/shape/model/secondary.py +31 -0
  369. pyflow/analysis/shape/model/slots.py +69 -0
  370. pyflow/analysis/shape/regionanalysis.py +152 -0
  371. pyflow/analysis/shape/transferfunctions.py +353 -0
  372. pyflow/analysis/storegraph/__init__.py +19 -0
  373. pyflow/analysis/storegraph/annotations.py +70 -0
  374. pyflow/analysis/storegraph/canonicalobjects.py +329 -0
  375. pyflow/analysis/storegraph/extendedtypes.py +311 -0
  376. pyflow/analysis/storegraph/setmanager.py +123 -0
  377. pyflow/analysis/storegraph/storegraph.py +577 -0
  378. pyflow/analysis/tools.py +112 -0
  379. pyflow/analysis/typeinfo/__init__.py +93 -0
  380. pyflow/analysis/typeinfo/_config.py +84 -0
  381. pyflow/analysis/typeinfo/annotation_resolver.py +483 -0
  382. pyflow/analysis/typeinfo/collector.py +361 -0
  383. pyflow/analysis/typeinfo/constants.py +378 -0
  384. pyflow/analysis/typeinfo/docstring_parser.py +289 -0
  385. pyflow/analysis/typeinfo/generic_binder.py +145 -0
  386. pyflow/analysis/typeinfo/gradual_typing.py +255 -0
  387. pyflow/analysis/typeinfo/models.py +43 -0
  388. pyflow/analysis/typeinfo/service.py +774 -0
  389. pyflow/analysis/typeinfo/string_subtype_inference.py +113 -0
  390. pyflow/analysis/typeinfo/string_subtypes.py +150 -0
  391. pyflow/analysis/typeinfo/stub_loader.py +667 -0
  392. pyflow/analysis/typeinfo/type_inference.py +747 -0
  393. pyflow/analysis/typeinfo/type_utils.py +361 -0
  394. pyflow/analysis/typeinfo/typesystem.py +2346 -0
  395. pyflow/analysis/typeinfo/typetracing.py +672 -0
  396. pyflow/api/__init__.py +94 -0
  397. pyflow/api/entrypoints/__init__.py +36 -0
  398. pyflow/api/entrypoints/declaration.py +345 -0
  399. pyflow/api/entrypoints/entry_point.py +59 -0
  400. pyflow/api/entrypoints/wrappers.py +83 -0
  401. pyflow/api/queries/__init__.py +65 -0
  402. pyflow/api/queries/_cfg_utils.py +53 -0
  403. pyflow/api/queries/_dataflow_ipa.py +29 -0
  404. pyflow/api/queries/_dataflow_reaching_defs.py +105 -0
  405. pyflow/api/queries/_dataflow_store_graph.py +152 -0
  406. pyflow/api/queries/_dataflow_taint.py +76 -0
  407. pyflow/api/queries/_models.py +177 -0
  408. pyflow/api/queries/call_graph.py +168 -0
  409. pyflow/api/queries/capabilities.py +106 -0
  410. pyflow/api/queries/context.py +152 -0
  411. pyflow/api/queries/control_flow.py +35 -0
  412. pyflow/api/queries/data_flow.py +157 -0
  413. pyflow/api/queries/engine.py +201 -0
  414. pyflow/api/queries/localization.py +8 -0
  415. pyflow/api/queries/service.py +339 -0
  416. pyflow/api/queries/tasks/__init__.py +8 -0
  417. pyflow/api/queries/tasks/code_localization.py +425 -0
  418. pyflow/api/queries/tasks/test_generation.py +338 -0
  419. pyflow/api/queries/test_generation.py +8 -0
  420. pyflow/application/__init__.py +109 -0
  421. pyflow/application/context.py +116 -0
  422. pyflow/application/errors.py +55 -0
  423. pyflow/application/makefile.py +213 -0
  424. pyflow/application/passes.py +515 -0
  425. pyflow/application/passmanager.py +755 -0
  426. pyflow/application/pipeline.py +459 -0
  427. pyflow/application/program.py +147 -0
  428. pyflow/checker/__init__.py +51 -0
  429. pyflow/checker/formatters/__init__.py +14 -0
  430. pyflow/checker/formatters/json.py +153 -0
  431. pyflow/checker/formatters/sarif.py +263 -0
  432. pyflow/checker/formatters/text.py +168 -0
  433. pyflow/checker/formatters/utils.py +17 -0
  434. pyflow/checker/llm/__init__.py +19 -0
  435. pyflow/checker/llm/exploit.py +129 -0
  436. pyflow/checker/llm/judge.py +105 -0
  437. pyflow/checker/llm/llm_utils.py +131 -0
  438. pyflow/checker/microbench.py +338 -0
  439. pyflow/checker/pattern/__init__.py +14 -0
  440. pyflow/checker/pattern/checkers/__init__.py +34 -0
  441. pyflow/checker/pattern/checkers/aws_security.py +234 -0
  442. pyflow/checker/pattern/checkers/blacklist_calls.py +54 -0
  443. pyflow/checker/pattern/checkers/blacklist_imports.py +73 -0
  444. pyflow/checker/pattern/checkers/class_pollution.py +459 -0
  445. pyflow/checker/pattern/checkers/command_injection.py +340 -0
  446. pyflow/checker/pattern/checkers/deserialization.py +373 -0
  447. pyflow/checker/pattern/checkers/django_security.py +285 -0
  448. pyflow/checker/pattern/checkers/exception_handling.py +317 -0
  449. pyflow/checker/pattern/checkers/exec_use.py +16 -0
  450. pyflow/checker/pattern/checkers/fastapi_security.py +291 -0
  451. pyflow/checker/pattern/checkers/flask_security.py +264 -0
  452. pyflow/checker/pattern/checkers/hardcoded_password.py +239 -0
  453. pyflow/checker/pattern/checkers/hardcoded_secrets.py +279 -0
  454. pyflow/checker/pattern/checkers/ldap_injection.py +281 -0
  455. pyflow/checker/pattern/checkers/path_traversal.py +124 -0
  456. pyflow/checker/pattern/checkers/shell_injection.py +46 -0
  457. pyflow/checker/pattern/checkers/sql_injection.py +170 -0
  458. pyflow/checker/pattern/checkers/sql_injection_enhanced.py +574 -0
  459. pyflow/checker/pattern/checkers/ssrf.py +419 -0
  460. pyflow/checker/pattern/checkers/template_security.py +310 -0
  461. pyflow/checker/pattern/checkers/weak_crypto.py +89 -0
  462. pyflow/checker/pattern/checkers/xxe_vulnerabilities.py +155 -0
  463. pyflow/checker/pattern/core/__init__.py +17 -0
  464. pyflow/checker/pattern/core/blacklist.py +569 -0
  465. pyflow/checker/pattern/core/config.py +15 -0
  466. pyflow/checker/pattern/core/constants.py +52 -0
  467. pyflow/checker/pattern/core/context.py +276 -0
  468. pyflow/checker/pattern/core/issue.py +325 -0
  469. pyflow/checker/pattern/core/manager.py +253 -0
  470. pyflow/checker/pattern/core/metrics.py +78 -0
  471. pyflow/checker/pattern/core/node_visitor.py +430 -0
  472. pyflow/checker/pattern/core/test_loader.py +41 -0
  473. pyflow/checker/pattern/core/test_properties.py +54 -0
  474. pyflow/checker/pattern/core/test_set.py +33 -0
  475. pyflow/checker/pattern/core/tester.py +244 -0
  476. pyflow/checker/pattern/core/utils.py +167 -0
  477. pyflow/checker/quality.py +374 -0
  478. pyflow/checker/semantic/__init__.py +16 -0
  479. pyflow/checker/semantic/core/__init__.py +23 -0
  480. pyflow/checker/semantic/core/base.py +26 -0
  481. pyflow/checker/semantic/core/context.py +270 -0
  482. pyflow/checker/semantic/core/issue.py +9 -0
  483. pyflow/checker/semantic/core/manager.py +150 -0
  484. pyflow/checker/semantic/core/runner.py +58 -0
  485. pyflow/checker/semantic/detectors/__init__.py +17 -0
  486. pyflow/checker/semantic/detectors/ast_helpers.py +114 -0
  487. pyflow/checker/semantic/detectors/leak.py +500 -0
  488. pyflow/checker/semantic/detectors/null_dereference.py +132 -0
  489. pyflow/checker/semantic/detectors/semantic_taint.py +2258 -0
  490. pyflow/checker/supply_chain.py +568 -0
  491. pyflow/cli/__init__.py +12 -0
  492. pyflow/cli/alias.py +397 -0
  493. pyflow/cli/callgraph.py +185 -0
  494. pyflow/cli/ir.py +461 -0
  495. pyflow/cli/main.py +125 -0
  496. pyflow/cli/optimize.py +603 -0
  497. pyflow/cli/security.py +1262 -0
  498. pyflow/cli/supply_chain.py +114 -0
  499. pyflow/config/nullness/django.json +21 -0
  500. pyflow/config/nullness/fastapi.json +17 -0
  501. pyflow/config/nullness/flask.json +37 -0
  502. pyflow/config/nullness/sql.json +21 -0
  503. pyflow/config/nullness/sqlalchemy.json +33 -0
  504. pyflow/config/nullness/stdlib.json +161 -0
  505. pyflow/config/rule-pack.schema.json +54 -0
  506. pyflow/config/taint/aiohttp.json +640 -0
  507. pyflow/config/taint/cloud.json +485 -0
  508. pyflow/config/taint/concurrency.json +25 -0
  509. pyflow/config/taint/django.json +710 -0
  510. pyflow/config/taint/falcon.json +375 -0
  511. pyflow/config/taint/fastapi.json +192 -0
  512. pyflow/config/taint/flask.json +504 -0
  513. pyflow/config/taint/injection.json +2294 -0
  514. pyflow/config/taint/network.json +367 -0
  515. pyflow/config/taint/nosql.json +166 -0
  516. pyflow/config/taint/pandas.json +463 -0
  517. pyflow/config/taint/requests.json +952 -0
  518. pyflow/config/taint/serialization.json +109 -0
  519. pyflow/config/taint/sql.json +730 -0
  520. pyflow/config/taint/sqlalchemy.json +235 -0
  521. pyflow/config/taint/stdlib.json +4388 -0
  522. pyflow/config/taint/tornado.json +151 -0
  523. pyflow/config/taint/xml.json +89 -0
  524. pyflow/config/typestate/concurrency.json +145 -0
  525. pyflow/config/typestate/network.json +130 -0
  526. pyflow/config/typestate/requests.json +88 -0
  527. pyflow/config/typestate/sql.json +107 -0
  528. pyflow/config/typestate/sqlalchemy.json +45 -0
  529. pyflow/config/typestate/stdlib.json +91 -0
  530. pyflow/config.py +30 -0
  531. pyflow/frontend/__init__.py +28 -0
  532. pyflow/frontend/ast_converter.py +2593 -0
  533. pyflow/frontend/class_hierarchy.py +665 -0
  534. pyflow/frontend/dependency_resolver.py +1836 -0
  535. pyflow/frontend/function_extractor.py +602 -0
  536. pyflow/frontend/object_manager.py +224 -0
  537. pyflow/frontend/programextractor.py +1033 -0
  538. pyflow/frontend/project_resolution.py +511 -0
  539. pyflow/frontend/source_locator.py +163 -0
  540. pyflow/frontend/stub_manager.py +425 -0
  541. pyflow/language/__init__.py +5 -0
  542. pyflow/language/asttools/__init__.py +34 -0
  543. pyflow/language/asttools/annotation.py +242 -0
  544. pyflow/language/asttools/antlrtranslator.py +344 -0
  545. pyflow/language/asttools/astpprint.py +132 -0
  546. pyflow/language/asttools/complexity.py +224 -0
  547. pyflow/language/asttools/decorators.py +71 -0
  548. pyflow/language/asttools/metaast/__init__.py +370 -0
  549. pyflow/language/asttools/metaast/codegeneration.py +622 -0
  550. pyflow/language/asttools/origin.py +83 -0
  551. pyflow/language/asttools/symbols.py +204 -0
  552. pyflow/language/asttools/visitors.py +179 -0
  553. pyflow/language/modules/__init__.py +18 -0
  554. pyflow/language/modules/_scope_graph.py +484 -0
  555. pyflow/language/modules/ast_helper.py +211 -0
  556. pyflow/language/modules/module_definitions.py +240 -0
  557. pyflow/language/modules/project_handler.py +110 -0
  558. pyflow/language/modules/transform.py +290 -0
  559. pyflow/language/modules/util.py +413 -0
  560. pyflow/language/python/__init__.py +21 -0
  561. pyflow/language/python/annotations.py +378 -0
  562. pyflow/language/python/ast.py +749 -0
  563. pyflow/language/python/collapser.py +604 -0
  564. pyflow/language/python/default_markers.py +8 -0
  565. pyflow/language/python/defuse.py +469 -0
  566. pyflow/language/python/fold.py +220 -0
  567. pyflow/language/python/program.py +371 -0
  568. pyflow/language/python/pythonbase.py +353 -0
  569. pyflow/language/python/pythonoutput.py +82 -0
  570. pyflow/language/python/simplecodegen.py +975 -0
  571. pyflow/optimization/__init__.py +29 -0
  572. pyflow/optimization/argumentnormalization.py +429 -0
  573. pyflow/optimization/callconverter.py +295 -0
  574. pyflow/optimization/clone.py +743 -0
  575. pyflow/optimization/codeinlining.py +587 -0
  576. pyflow/optimization/convertboolelimination.py +111 -0
  577. pyflow/optimization/cullprogram.py +155 -0
  578. pyflow/optimization/dataflow/__init__.py +17 -0
  579. pyflow/optimization/dataflow/base.py +780 -0
  580. pyflow/optimization/dataflow/forward.py +681 -0
  581. pyflow/optimization/dataflow/reverse.py +454 -0
  582. pyflow/optimization/dce.py +354 -0
  583. pyflow/optimization/fold.py +780 -0
  584. pyflow/optimization/loadelimination.py +342 -0
  585. pyflow/optimization/methodcall.py +554 -0
  586. pyflow/optimization/rewrite.py +129 -0
  587. pyflow/optimization/simplify.py +143 -0
  588. pyflow/optimization/storeelimination.py +129 -0
  589. pyflow/optimization/termrewrite.py +287 -0
  590. pyflow/stats/__init__.py +436 -0
  591. pyflow/stubs/__init__.py +34 -0
  592. pyflow/stubs/__pycache__/__init__.cpython-313.pyc +0 -0
  593. pyflow/stubs/__pycache__/lltranslator.cpython-313.pyc +0 -0
  594. pyflow/stubs/__pycache__/stubcollector.cpython-313.pyc +0 -0
  595. pyflow/stubs/lltranslator.py +493 -0
  596. pyflow/stubs/std/__init__.py +83 -0
  597. pyflow/stubs/std/__pycache__/__init__.cpython-313.pyc +0 -0
  598. pyflow/stubs/std/__pycache__/argparse_stubs.cpython-313.pyc +0 -0
  599. pyflow/stubs/std/__pycache__/collections_stubs.cpython-313.pyc +0 -0
  600. pyflow/stubs/std/__pycache__/container.cpython-313.pyc +0 -0
  601. pyflow/stubs/std/__pycache__/copy_stubs.cpython-313.pyc +0 -0
  602. pyflow/stubs/std/__pycache__/csv_stubs.cpython-313.pyc +0 -0
  603. pyflow/stubs/std/__pycache__/datetime_stubs.cpython-313.pyc +0 -0
  604. pyflow/stubs/std/__pycache__/functools_stubs.cpython-313.pyc +0 -0
  605. pyflow/stubs/std/__pycache__/hashlib_stubs.cpython-313.pyc +0 -0
  606. pyflow/stubs/std/__pycache__/interpreter.cpython-313.pyc +0 -0
  607. pyflow/stubs/std/__pycache__/io_stubs.cpython-313.pyc +0 -0
  608. pyflow/stubs/std/__pycache__/itertools_stubs.cpython-313.pyc +0 -0
  609. pyflow/stubs/std/__pycache__/json_stubs.cpython-313.pyc +0 -0
  610. pyflow/stubs/std/__pycache__/llfunc.cpython-313.pyc +0 -0
  611. pyflow/stubs/std/__pycache__/logging_stubs.cpython-313.pyc +0 -0
  612. pyflow/stubs/std/__pycache__/mathstubs.cpython-313.pyc +0 -0
  613. pyflow/stubs/std/__pycache__/operator_stubs.cpython-313.pyc +0 -0
  614. pyflow/stubs/std/__pycache__/os_stubs.cpython-313.pyc +0 -0
  615. pyflow/stubs/std/__pycache__/pathlib_stubs.cpython-313.pyc +0 -0
  616. pyflow/stubs/std/__pycache__/pickle_stubs.cpython-313.pyc +0 -0
  617. pyflow/stubs/std/__pycache__/random.cpython-313.pyc +0 -0
  618. pyflow/stubs/std/__pycache__/re_stubs.cpython-313.pyc +0 -0
  619. pyflow/stubs/std/__pycache__/sampler.cpython-313.pyc +0 -0
  620. pyflow/stubs/std/__pycache__/shutil_stubs.cpython-313.pyc +0 -0
  621. pyflow/stubs/std/__pycache__/subprocess_stubs.cpython-313.pyc +0 -0
  622. pyflow/stubs/std/__pycache__/sys_stubs.cpython-313.pyc +0 -0
  623. pyflow/stubs/std/__pycache__/tempfile_stubs.cpython-313.pyc +0 -0
  624. pyflow/stubs/std/__pycache__/threading_stubs.cpython-313.pyc +0 -0
  625. pyflow/stubs/std/__pycache__/time_stubs.cpython-313.pyc +0 -0
  626. pyflow/stubs/std/argparse_stubs.py +200 -0
  627. pyflow/stubs/std/collections_stubs.py +77 -0
  628. pyflow/stubs/std/container.py +374 -0
  629. pyflow/stubs/std/copy_stubs.py +54 -0
  630. pyflow/stubs/std/csv_stubs.py +187 -0
  631. pyflow/stubs/std/datetime_stubs.py +70 -0
  632. pyflow/stubs/std/functools_stubs.py +61 -0
  633. pyflow/stubs/std/hashlib_stubs.py +198 -0
  634. pyflow/stubs/std/interpreter.py +360 -0
  635. pyflow/stubs/std/io_stubs.py +339 -0
  636. pyflow/stubs/std/itertools_stubs.py +89 -0
  637. pyflow/stubs/std/json_stubs.py +40 -0
  638. pyflow/stubs/std/llfunc.py +240 -0
  639. pyflow/stubs/std/logging_stubs.py +295 -0
  640. pyflow/stubs/std/mathstubs.py +393 -0
  641. pyflow/stubs/std/objects/__init__.py +9 -0
  642. pyflow/stubs/std/objects/__pycache__/__init__.cpython-313.pyc +0 -0
  643. pyflow/stubs/std/objects/__pycache__/float.cpython-313.pyc +0 -0
  644. pyflow/stubs/std/objects/__pycache__/int.cpython-313.pyc +0 -0
  645. pyflow/stubs/std/objects/__pycache__/str.cpython-313.pyc +0 -0
  646. pyflow/stubs/std/objects/float.py +248 -0
  647. pyflow/stubs/std/objects/int.py +221 -0
  648. pyflow/stubs/std/objects/str.py +175 -0
  649. pyflow/stubs/std/operator_stubs.py +148 -0
  650. pyflow/stubs/std/os_stubs.py +727 -0
  651. pyflow/stubs/std/pathlib_stubs.py +364 -0
  652. pyflow/stubs/std/pickle_stubs.py +97 -0
  653. pyflow/stubs/std/random.py +29 -0
  654. pyflow/stubs/std/re_stubs.py +178 -0
  655. pyflow/stubs/std/sampler.py +17 -0
  656. pyflow/stubs/std/shutil_stubs.py +212 -0
  657. pyflow/stubs/std/subprocess_stubs.py +149 -0
  658. pyflow/stubs/std/sys_stubs.py +226 -0
  659. pyflow/stubs/std/tempfile_stubs.py +129 -0
  660. pyflow/stubs/std/threading_stubs.py +328 -0
  661. pyflow/stubs/std/time_stubs.py +283 -0
  662. pyflow/stubs/stubcollector.py +463 -0
  663. pyflow/util/PADS/Automata.py +640 -0
  664. pyflow/util/PADS/BFS.py +28 -0
  665. pyflow/util/PADS/Biconnectivity.py +270 -0
  666. pyflow/util/PADS/Bipartite.py +89 -0
  667. pyflow/util/PADS/BipartiteMatching.py +129 -0
  668. pyflow/util/PADS/CardinalityMatching.py +316 -0
  669. pyflow/util/PADS/Chordal.py +33 -0
  670. pyflow/util/PADS/CubicHam.py +351 -0
  671. pyflow/util/PADS/DFS.py +100 -0
  672. pyflow/util/PADS/Eratosthenes.py +138 -0
  673. pyflow/util/PADS/GraphExamples.py +36 -0
  674. pyflow/util/PADS/Graphs.py +82 -0
  675. pyflow/util/PADS/GrayGraph.py +36 -0
  676. pyflow/util/PADS/IntegerPartitions.py +317 -0
  677. pyflow/util/PADS/LCA.py +349 -0
  678. pyflow/util/PADS/LCS.py +38 -0
  679. pyflow/util/PADS/LexBFS.py +32 -0
  680. pyflow/util/PADS/LongestIncreasingSubsequence.py +65 -0
  681. pyflow/util/PADS/Medium.py +414 -0
  682. pyflow/util/PADS/MinimumSpanningTree.py +26 -0
  683. pyflow/util/PADS/OrderedSequence.py +133 -0
  684. pyflow/util/PADS/PartialCube.py +227 -0
  685. pyflow/util/PADS/PartialOrder.py +129 -0
  686. pyflow/util/PADS/PartitionRefinement.py +85 -0
  687. pyflow/util/PADS/ReadUndirectedGraph.py +431 -0
  688. pyflow/util/PADS/Repetitivity.py +160 -0
  689. pyflow/util/PADS/SMAWK.py +190 -0
  690. pyflow/util/PADS/Sequence.py +118 -0
  691. pyflow/util/PADS/StrongConnectivity.py +106 -0
  692. pyflow/util/PADS/Sudoku.py +2028 -0
  693. pyflow/util/PADS/UnionFind.py +63 -0
  694. pyflow/util/PADS/Util.py +28 -0
  695. pyflow/util/PADS/Wrap.py +79 -0
  696. pyflow/util/PADS/__init__.py +13 -0
  697. pyflow/util/PADS/xyzGraph.py +127 -0
  698. pyflow/util/__init__.py +19 -0
  699. pyflow/util/antlr3/__init__.py +134 -0
  700. pyflow/util/antlr3/compat.py +12 -0
  701. pyflow/util/antlr3/constants.py +24 -0
  702. pyflow/util/antlr3/dfa.py +179 -0
  703. pyflow/util/antlr3/dottreegen.py +170 -0
  704. pyflow/util/antlr3/exceptions.py +346 -0
  705. pyflow/util/antlr3/extras.py +11 -0
  706. pyflow/util/antlr3/main.py +198 -0
  707. pyflow/util/antlr3/recognizers.py +1341 -0
  708. pyflow/util/antlr3/streams.py +1250 -0
  709. pyflow/util/antlr3/tokens.py +370 -0
  710. pyflow/util/antlr3/tree.py +2190 -0
  711. pyflow/util/antlr3/treewizard.py +566 -0
  712. pyflow/util/application/__init__.py +13 -0
  713. pyflow/util/application/async_utils.py +101 -0
  714. pyflow/util/application/compilerexceptions.py +21 -0
  715. pyflow/util/application/console.py +235 -0
  716. pyflow/util/application/errorhandler.py +241 -0
  717. pyflow/util/canonical.py +204 -0
  718. pyflow/util/debug/__init__.py +11 -0
  719. pyflow/util/debug/blame.py +94 -0
  720. pyflow/util/debug/debugger.py +105 -0
  721. pyflow/util/debug/trace.py +56 -0
  722. pyflow/util/graphalgorithim/__init__.py +17 -0
  723. pyflow/util/graphalgorithim/basic.py +77 -0
  724. pyflow/util/graphalgorithim/color.py +104 -0
  725. pyflow/util/graphalgorithim/djtree.py +299 -0
  726. pyflow/util/graphalgorithim/dominator.py +531 -0
  727. pyflow/util/graphalgorithim/exclusiongraph.py +624 -0
  728. pyflow/util/graphalgorithim/merge.py +221 -0
  729. pyflow/util/io/__init__.py +6 -0
  730. pyflow/util/io/dot.py +540 -0
  731. pyflow/util/io/filesystem.py +210 -0
  732. pyflow/util/io/formatting.py +71 -0
  733. pyflow/util/io/report.py +224 -0
  734. pyflow/util/io/xmloutput.py +270 -0
  735. pyflow/util/json_dict.py +92 -0
  736. pyflow/util/monkeypatch/__init__.py +21 -0
  737. pyflow/util/monkeypatch/xcollections.py +206 -0
  738. pyflow/util/monkeypatch/xmath.py +108 -0
  739. pyflow/util/monkeypatch/xnamedtuple.py +180 -0
  740. pyflow/util/monkeypatch/xtypes.py +56 -0
  741. pyflow/util/orderedset.py +420 -0
  742. pyflow/util/pydot.py +1998 -0
  743. pyflow/util/python/__init__.py +136 -0
  744. pyflow/util/python/apply.py +180 -0
  745. pyflow/util/python/calling.py +558 -0
  746. pyflow/util/python/opnames.py +153 -0
  747. pyflow/util/randomness.py +230 -0
  748. pyflow/util/singleton.py +112 -0
  749. pyflow/util/tvl.py +321 -0
  750. pyflow/util/typedispatch.py +342 -0
  751. pyflow/util/unionfind.py +169 -0
  752. pyflow_analysis-0.1.0.dist-info/METADATA +184 -0
  753. pyflow_analysis-0.1.0.dist-info/RECORD +757 -0
  754. pyflow_analysis-0.1.0.dist-info/WHEEL +5 -0
  755. pyflow_analysis-0.1.0.dist-info/entry_points.txt +2 -0
  756. pyflow_analysis-0.1.0.dist-info/licenses/LICENSE.txt +202 -0
  757. pyflow_analysis-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,664 @@
1
+ from abc import ABC, abstractmethod
2
+ import ast
3
+ import logging
4
+ from typing import TYPE_CHECKING, Any, Optional, Dict, Tuple
5
+
6
+ from .processor import Processor
7
+ from ..points_to_set import PointsToSet
8
+ from ..constraints import CallConstraint, AllocConstraint, LoadConstraint
9
+ from ..object import (
10
+ AllocKind,
11
+ FunctionObject,
12
+ MethodObject,
13
+ ClassObject,
14
+ InstanceObject,
15
+ BuiltinObject,
16
+ BuiltinFunctionObject,
17
+ BuiltinMethodObject,
18
+ BuiltinClassObject,
19
+ BuiltinInstanceObject,
20
+ AllocSite,
21
+ TupleObject,
22
+ DictObject,
23
+ )
24
+ from ..context import Ctx, Scope, AbstractContext
25
+ from ..variable import VariableKind, Variable
26
+ from ..unknown_tracker import UnknownKind
27
+ from ..heap_model import key, attr
28
+ from pyflow.analysis.alias.kcfa._pythonstan.graph.call_graph import CallEdge, CallKind
29
+ from pyflow.analysis.alias.kcfa._pythonstan.ir.ir_statements import IRFunc, IRAssign
30
+
31
+ if TYPE_CHECKING:
32
+ from ..pointer_flow_graph import NormalNode
33
+ from ..solver import PointerSolver
34
+ from ..constraints import CallConstraint, Constraint
35
+ from ..object import AbstractObject
36
+
37
+ logger = logging.getLogger(__name__)
38
+
39
+ __all__ = ["NormalCallProcessor"]
40
+
41
+
42
+ class NormalCallProcessor(Processor):
43
+ def __init__(self) -> None:
44
+ self._default_alloc_sites: Dict[Tuple[IRFunc, str, int, AllocKind], AllocSite] = {}
45
+
46
+ def handle_call(self, solver: 'PointerSolver', target: 'Ctx[Any]', scope: 'Scope', constraint: 'Constraint', callee_obj: 'AbstractObject') -> bool:
47
+ if isinstance(callee_obj, MethodObject):
48
+ return self._handle_method_call(solver, scope, scope.context, constraint, callee_obj)
49
+ if isinstance(callee_obj, FunctionObject):
50
+ return self._handle_function_call(solver, scope, scope.context, constraint, callee_obj)
51
+ if isinstance(callee_obj, (BuiltinObject, BuiltinFunctionObject, BuiltinMethodObject, BuiltinClassObject, BuiltinInstanceObject)) or callee_obj.kind == AllocKind.BUILTIN:
52
+ return self._handle_builtin_call(solver, scope, scope.context, constraint, callee_obj)
53
+ if isinstance(callee_obj, ClassObject):
54
+ return self._handle_class_call(solver, scope, scope.context, constraint, callee_obj)
55
+ if isinstance(callee_obj, InstanceObject):
56
+ return self._handle_object_call(solver, scope, scope.context, constraint, callee_obj)
57
+ return self._handle_object_call(solver, scope, scope.context, constraint, callee_obj)
58
+
59
+ def _handle_builtin_call(
60
+ self,
61
+ solver: 'PointerSolver',
62
+ scope: 'Scope',
63
+ context: 'AbstractContext',
64
+ call: 'CallConstraint',
65
+ builtin_obj: 'AbstractObject',
66
+ ) -> bool:
67
+ if solver._handle_builtin_call(scope, context, call, builtin_obj):
68
+ return True
69
+ return True
70
+
71
+ def _handle_class_call(
72
+ self,
73
+ solver: 'PointerSolver',
74
+ scope: 'Scope',
75
+ context: 'AbstractContext',
76
+ call: 'CallConstraint',
77
+ class_obj: 'ClassObject',
78
+ ) -> bool:
79
+ return solver._handle_class_instantiation(scope, context, call, class_obj)
80
+
81
+ def _handle_object_call(
82
+ self,
83
+ solver: 'PointerSolver',
84
+ scope: 'Scope',
85
+ context: 'AbstractContext',
86
+ call: 'CallConstraint',
87
+ callee_obj: 'AbstractObject',
88
+ ) -> bool:
89
+ if call.callee.name.startswith("$call@"):
90
+ return False
91
+ call_var = solver.variable_factory.make_variable(f"$call@{call.call_site.short_id()}")
92
+ ctx_call_var = solver.state.get_variable(scope, context, call_var)
93
+ call_field = solver.state.get_field(scope, context, callee_obj, attr("__call__"))
94
+ solver.state._add_var_points_flow(call_field, ctx_call_var)
95
+ solver.add_constraint(
96
+ scope,
97
+ context,
98
+ CallConstraint(
99
+ callee=call_var,
100
+ args=call.args,
101
+ kwargs=call.kwargs,
102
+ target=call.target,
103
+ call_site=call.call_site,
104
+ ),
105
+ )
106
+ return True
107
+
108
+ def _make_default_alloc_site(
109
+ self,
110
+ func_ir: IRFunc,
111
+ param_name: str,
112
+ default_index: int,
113
+ kind: AllocKind,
114
+ value: Any,
115
+ ) -> AllocSite:
116
+ key = (func_ir, param_name, default_index, kind)
117
+ alloc_site = self._default_alloc_sites.get(key)
118
+ if alloc_site is None:
119
+ default_var_name = self._default_var_name(func_ir, param_name, default_index, kind)
120
+ const_assign = IRAssign(
121
+ ast.Assign(
122
+ targets=[ast.Name(id=default_var_name, ctx=ast.Store())],
123
+ value=ast.Constant(value=value),
124
+ )
125
+ )
126
+ alloc_site = AllocSite.from_ir_node(const_assign, kind)
127
+ self._default_alloc_sites[key] = alloc_site
128
+ return alloc_site
129
+
130
+ @staticmethod
131
+ def _default_var_name(func_ir: IRFunc, param_name: str, default_index: int, kind: AllocKind) -> str:
132
+ return f"$default_{kind.value}_{id(func_ir)}_{param_name}_{default_index}"
133
+
134
+ def _materialize_default(
135
+ self,
136
+ solver: 'PointerSolver',
137
+ func_ir: IRFunc,
138
+ def_scope: Scope,
139
+ def_context: AbstractContext,
140
+ param_name: str,
141
+ default_index: int,
142
+ default_expr: ast.expr,
143
+ ) -> 'Ctx[Variable]':
144
+ default_var_name = self._default_var_name(func_ir, param_name, default_index, AllocKind.CONSTANT)
145
+ default_var = solver.variable_factory.make_variable(default_var_name)
146
+ default_ctx_var = solver.state.get_variable(def_scope, def_context, default_var)
147
+
148
+ if isinstance(default_expr, ast.Constant):
149
+ alloc_site = self._make_default_alloc_site(
150
+ func_ir=func_ir,
151
+ param_name=param_name,
152
+ default_index=default_index,
153
+ kind=AllocKind.CONSTANT,
154
+ value=default_expr.value,
155
+ )
156
+ solver.add_constraint(
157
+ def_scope,
158
+ def_context,
159
+ AllocConstraint(target=default_var, alloc_site=alloc_site),
160
+ )
161
+ return default_ctx_var
162
+
163
+ if isinstance(default_expr, ast.Name):
164
+ source_var = solver.variable_factory.make_variable(default_expr.id)
165
+ source_ctx = solver.state.get_variable(def_scope, def_context, source_var)
166
+ solver.state._add_var_points_flow(source_ctx, default_ctx_var)
167
+ return default_ctx_var
168
+
169
+ if isinstance(default_expr, ast.Attribute) and isinstance(default_expr.value, ast.Name):
170
+ base_var = solver.variable_factory.make_variable(default_expr.value.id)
171
+ solver.add_constraint(
172
+ def_scope,
173
+ def_context,
174
+ LoadConstraint(
175
+ base=base_var,
176
+ field=attr(default_expr.attr),
177
+ target=default_var,
178
+ ),
179
+ )
180
+ return default_ctx_var
181
+
182
+ alloc_site = self._make_default_alloc_site(
183
+ func_ir=func_ir,
184
+ param_name=param_name,
185
+ default_index=default_index,
186
+ kind=AllocKind.UNKNOWN,
187
+ value=None,
188
+ )
189
+ solver.add_constraint(
190
+ def_scope,
191
+ def_context,
192
+ AllocConstraint(target=default_var, alloc_site=alloc_site),
193
+ )
194
+ return default_ctx_var
195
+
196
+ def _handle_method_call(self, solver: 'PointerSolver', scope: 'Scope', context: 'AbstractContext', call: 'CallConstraint', method_obj: 'MethodObject') -> bool:
197
+ # logger.info(f"Handling method call: {call.call_site} -> {method_obj.alloc_site.stmt.get_qualname()}")
198
+
199
+ if not isinstance(method_obj, MethodObject):
200
+ logger.info(f"is not method object, {type(method_obj)} got!")
201
+ return False
202
+
203
+ func_ir: IRFunc = method_obj.alloc_site.stmt
204
+ assert isinstance(func_ir, IRFunc), f"MethodObject alloc site stmt should be IRFunc, {type(func_ir)} got!"
205
+ func_name = func_ir.get_qualname()
206
+
207
+ if func_ir.is_static_method:
208
+ return self._handle_function_call(solver, scope, context, call, method_obj)
209
+
210
+ if func_ir.is_class_method:
211
+ holder_obj = method_obj.class_obj
212
+ else:
213
+ holder_obj = method_obj.instance_obj
214
+ if holder_obj is None:
215
+ return self._handle_function_call(solver, scope, context, call, method_obj)
216
+
217
+ if not holder_obj:
218
+ logger.info(f"No holder got in {method_obj}")
219
+ return False
220
+
221
+ self_var = solver.state.get_variable(
222
+ scope,
223
+ context,
224
+ solver.variable_factory.make_variable(f"$self@{call.call_site.short_id()}")
225
+ )
226
+ solver.handle_new_points_to(self_var, scope, PointsToSet.singleton(holder_obj))
227
+
228
+ args = [solver.state.get_variable(scope, context, arg) for arg in call.args]
229
+ args.insert(0, self_var)
230
+ kwargs = {k: solver.state.get_variable(scope, context, arg) for k, arg in call.kwargs}
231
+
232
+ call_context = solver.context_selector.select_call_context(
233
+ call.call_site,
234
+ context,
235
+ holder_obj,
236
+ params=frozenset(args) | frozenset(kwargs.items())
237
+ )
238
+
239
+ logger.debug(f"Handling function call: {call.call_site} -> {method_obj.alloc_site.stmt}")
240
+
241
+ method_scope = solver.state.get_internal_scope(holder_obj)
242
+ callee_scope = Scope.new(method_obj, method_scope.module, call_context, func_ir, method_scope)
243
+ assert holder_obj
244
+
245
+ if func_ir.is_class_method:
246
+ call_kind = CallKind.CLASS
247
+ else:
248
+ call_kind = CallKind.INSTANCE
249
+ call_edge = CallEdge(kind=call_kind, callsite=Ctx(context, scope, call.call_site), callee=callee_scope)
250
+ # if self.state.call_graph.has_edge(edge):
251
+ # return False
252
+
253
+ self._dispatch_closure(solver, method_obj, call_context, scope, callee_scope)
254
+
255
+ alloc_site = method_obj.alloc_site
256
+ old_scope = solver.ir_translator._current_scope
257
+ solver.ir_translator._current_scope = alloc_site.stmt
258
+
259
+ try:
260
+ body_constraints = solver.ir_translator.translate_function(func_ir)
261
+ except Exception as e:
262
+ solver._unknown_tracker.record(
263
+ UnknownKind.TRANSLATION_ERROR,
264
+ str(call.call_site),
265
+ f"Error translating function body: {str(e)}",
266
+ context=func_name
267
+ )
268
+
269
+ if solver.config.verbose:
270
+ logger.warning(f"[UNKNOWN] Translation error for {func_name}: {e}")
271
+
272
+ body_constraints = []
273
+ finally:
274
+ solver.ir_translator._current_scope = old_scope
275
+ # self.ir_translator._current_context = old_context
276
+
277
+ changed = False
278
+ for constraint in body_constraints:
279
+ solver.add_constraint(callee_scope, call_context, constraint)
280
+ changed = True
281
+
282
+ self._match_parameters(solver, method_obj, call, scope, callee_scope, context, call_context, self_var)
283
+
284
+ if call.target:
285
+ # Use TEMPORARY kind for $return so it's shared across all contexts in the same function
286
+ ret = solver.variable_factory.make_variable("$return", VariableKind.TEMPORARY)
287
+ ret_var = solver.state.get_variable(callee_scope, call_context, ret)
288
+ target_var = solver.state.get_variable(scope, context, call.target)
289
+ solver.state._add_var_points_flow(ret_var, target_var)
290
+
291
+ solver.state.call_graph.add_edge(call_edge)
292
+ logger.debug(f"Adding call edge: {call_edge}")
293
+
294
+ # Debug monitoring: record call edge creation
295
+ if solver._debug_monitor and solver._debug_monitor.enabled:
296
+ caller_name = str(scope.stmt.get_qualname() if hasattr(scope.stmt, 'get_qualname') else scope.stmt)
297
+ callee_name = str(call_edge.callee.stmt.get_qualname() if hasattr(call_edge.callee.stmt, 'get_qualname') else call_edge.callee.stmt)
298
+ solver._debug_monitor.record_call_edge_created(
299
+ caller=caller_name,
300
+ callee=callee_name,
301
+ call_site=str(call.call_site),
302
+ callee_type="method"
303
+ )
304
+
305
+ return True
306
+
307
+ def _handle_function_call(self, solver: 'PointerSolver', scope: 'Scope', context: 'AbstractContext', call: 'CallConstraint', func_obj: 'AbstractObject') -> bool:
308
+ """Handle function call: analyze function body with parameter bindings.
309
+ 1. Selects calling context
310
+ 2. Translates function body to constraints
311
+ 3. Generates parameter passing constraints
312
+ 4. Connects return value to caller
313
+ 5. Adds call edge to call graph
314
+ """
315
+ # logger.info(f"Handling function call: {call.call_site} -> {func_obj.alloc_site.stmt}")
316
+
317
+ if not isinstance(func_obj, FunctionObject):
318
+ logger.info(f"is not function object, {type(func_obj)} got!")
319
+ return False
320
+
321
+ func_ir: IRFunc = func_obj.alloc_site.stmt
322
+ func_name = func_ir.get_name()
323
+ alloc_site = func_obj.alloc_site
324
+ # logger.info(f"Handling function call: {call.call_site} -> {alloc_site}")
325
+ args = [solver.state.get_variable(scope, context, arg) for arg in call.args]
326
+ kwargs = {k: solver.state.get_variable(scope, context, arg) for k, arg in call.kwargs}
327
+
328
+ call_context = solver.context_selector.select_call_context(
329
+ call.call_site,
330
+ context,
331
+ None, # No receiver ffor regular functions
332
+ params=frozenset(args) | frozenset(kwargs.items())
333
+ )
334
+
335
+ logger.debug(f"Handling function call: {call.call_site} -> {func_obj.alloc_site.stmt}")
336
+
337
+ # func_ir = self.function_registry[func_name]
338
+ # method_scope = solver.state.obj_scope[func_obj]
339
+ alloc_site = func_obj.alloc_site
340
+ # callee_scope = Scope.new(func_obj, method_scope.module, call_context, func_ir, method_scope)
341
+ callee_scope = Scope.new(func_obj, scope.module, call_context, func_ir, scope)
342
+ call_kind = CallKind.STATIC if func_ir.is_static_method else CallKind.FUNCTION
343
+ call_edge = CallEdge(kind=call_kind, callsite=Ctx(context, scope, call.call_site), callee=callee_scope)
344
+ # if self.state.call_graph.has_edge(edge):
345
+ # return False
346
+
347
+ self._dispatch_closure(solver, func_obj, call_context, scope, callee_scope)
348
+
349
+ old_scope = solver.ir_translator._current_scope
350
+ solver.ir_translator._current_scope = alloc_site.stmt
351
+
352
+ try:
353
+ body_constraints = solver.ir_translator.translate_function(func_ir)
354
+ except Exception as e:
355
+ solver._unknown_tracker.record(
356
+ UnknownKind.TRANSLATION_ERROR,
357
+ str(call.call_site),
358
+ f"Error translating function body: {str(e)}",
359
+ context=func_name
360
+ )
361
+
362
+ if solver.config.verbose:
363
+ logger.warning(f"[UNKNOWN] Translation error for {func_name}: {e}")
364
+
365
+ body_constraints = []
366
+ finally:
367
+ solver.ir_translator._current_scope = old_scope
368
+
369
+ changed = False
370
+ for constraint in body_constraints:
371
+ solver.add_constraint(callee_scope, call_context, constraint)
372
+ changed = True
373
+
374
+ self._match_parameters(solver, func_obj, call, scope, callee_scope, context, call_context)
375
+
376
+ if call.target:
377
+ # Use TEMPORARY kind for $return so it's shared across all contexts in the same function
378
+ ret = solver.variable_factory.make_variable("$return", VariableKind.TEMPORARY)
379
+ ret_var = solver.state.get_variable(callee_scope, call_context, ret)
380
+ target_var = solver.state.get_variable(scope, context, call.target)
381
+ if solver.config.verbose:
382
+ logger.info(f"[RETURN] Connecting return: {ret_var} -> {target_var}")
383
+ logger.info(f" Callee scope: {callee_scope.stmt.get_qualname() if hasattr(callee_scope.stmt, 'get_qualname') else callee_scope.stmt}, context={call_context}")
384
+ logger.info(f" Caller scope (input): {scope.stmt.get_qualname() if hasattr(scope.stmt, 'get_qualname') else scope.stmt}, context={context}")
385
+ logger.info(f" Target var scope (result): {target_var.scope.stmt.get_qualname() if hasattr(target_var.scope.stmt, 'get_qualname') else target_var.scope.stmt}, context={target_var.context}")
386
+ logger.info(f" Call target var: {call.target.name}, kind={call.target.kind}")
387
+ solver.state._add_var_points_flow(ret_var, target_var)
388
+
389
+ solver.state.call_graph.add_edge(call_edge)
390
+ logger.debug(f"Adding call edge: {call_edge}")
391
+
392
+ # Debug monitoring: record call edge creation
393
+ if solver._debug_monitor and solver._debug_monitor.enabled:
394
+ caller_name = str(scope.stmt.get_qualname() if hasattr(scope.stmt, 'get_qualname') else scope.stmt)
395
+ callee_name = str(call_edge.callee.stmt.get_qualname() if hasattr(call_edge.callee.stmt, 'get_qualname') else call_edge.callee.stmt)
396
+ solver._debug_monitor.record_call_edge_created(
397
+ caller=caller_name,
398
+ callee=callee_name,
399
+ call_site=str(call.call_site),
400
+ callee_type="function"
401
+ )
402
+
403
+ return True
404
+
405
+ def _dispatch_closure(self, solver: 'PointerSolver', callee_obj: 'FunctionObject', call_context: 'AbstractContext', scope: 'Scope', callee_scope: 'Scope'):
406
+ """Dispatch closure: dispatch closure variables to the callee."""
407
+ state = solver.state
408
+
409
+ cell_vars = state.get_cell_vars(callee_obj)
410
+ for name, var in cell_vars.items():
411
+ target_var = state.get_variable(callee_scope, call_context, solver.variable_factory.make_variable(name))
412
+ state._add_var_points_flow(var, target_var)
413
+
414
+ nonlocal_vars = state.get_nonlocal_vars(callee_obj)
415
+ for name, var in nonlocal_vars.items():
416
+ state.set_variable(callee_scope, call_context, var.content, var)
417
+
418
+ global_vars = state.get_global_vars(callee_obj)
419
+ for name, var in global_vars.items():
420
+ var = state.get_variable(scope.module, scope.module.context, solver.variable_factory.make_variable(name))
421
+ state.set_variable(callee_scope, call_context, var.content, var)
422
+
423
+ def _match_parameters(self,
424
+ solver: 'PointerSolver',
425
+ callee_obj: 'FunctionObject',
426
+ call: 'CallConstraint',
427
+ scope: 'Scope',
428
+ callee_scope: 'Scope',
429
+ context: 'AbstractContext',
430
+ call_context: 'AbstractContext',
431
+ self_var: Optional['Ctx[Variable]'] = None
432
+ ) -> None:
433
+ """Match parameters: match arguments to parameters."""
434
+ state = solver.state
435
+
436
+ args = [state.get_variable(scope, context, arg) for arg in call.args]
437
+ if self_var is not None:
438
+ args.insert(0, self_var)
439
+ kwargs = {k: state.get_variable(scope, context, arg) for k, arg in call.kwargs}
440
+
441
+ method_obj = callee_obj
442
+ func_ir: IRFunc = method_obj.alloc_site.stmt
443
+ func_name = func_ir.get_qualname()
444
+
445
+ if hasattr(func_ir, 'args'):
446
+ func_args = func_ir.args
447
+ arg_vars = args # Positional argument variables from call site
448
+ kwarg_vars = kwargs.copy() # Keyword argument variables from call site (dict: name -> Variable)
449
+
450
+ positional_params = []
451
+ if hasattr(func_args, 'posonlyargs') and func_args.posonlyargs:
452
+ positional_params.extend(func_args.posonlyargs)
453
+ if func_args.args:
454
+ positional_params.extend(func_args.args)
455
+
456
+ positional_defaults = {}
457
+ if func_args.defaults:
458
+ first_default_idx = len(positional_params) - len(func_args.defaults)
459
+ for idx, default_expr in enumerate(func_args.defaults):
460
+ param = positional_params[first_default_idx + idx]
461
+ positional_defaults[param.arg] = (default_expr, first_default_idx + idx)
462
+
463
+ # Track which parameters have been bound
464
+ arg_index = 0
465
+ consumed_kwargs = set() # Track which keyword arguments have been matched
466
+
467
+ # 1. Handle positional-only parameters (Python 3.8+)
468
+ # These can ONLY be filled by positional arguments, not keywords
469
+ if hasattr(func_args, 'posonlyargs') and func_args.posonlyargs:
470
+ for param in func_args.posonlyargs:
471
+ param_name = param.arg
472
+ param_var = state.get_variable(
473
+ callee_scope,
474
+ call_context,
475
+ solver.variable_factory.make_variable(param_name)
476
+ )
477
+
478
+ if arg_index < len(arg_vars):
479
+ # Bind positional argument to parameter
480
+ state._add_var_points_flow(arg_vars[arg_index], param_var)
481
+ arg_index += 1
482
+ else:
483
+ default_entry = positional_defaults.get(param_name)
484
+ if default_entry is not None:
485
+ default_expr, default_idx = default_entry
486
+ def_scope = callee_obj.container_scope
487
+ def_context = def_scope.context
488
+ default_ctx = self._materialize_default(
489
+ solver=solver,
490
+ func_ir=func_ir,
491
+ def_scope=def_scope,
492
+ def_context=def_context,
493
+ param_name=param_name,
494
+ default_index=default_idx,
495
+ default_expr=default_expr,
496
+ )
497
+ state._add_var_points_flow(default_ctx, param_var)
498
+ else:
499
+ solver._unknown_tracker.record(
500
+ UnknownKind.MISSING_ARGUMENT,
501
+ str(call.call_site),
502
+ f"Required positional-only parameter {param_name} not provided",
503
+ context=func_name
504
+ )
505
+
506
+ # 2. Handle regular positional/keyword parameters
507
+ # These can be filled by either positional OR keyword arguments
508
+ if func_args.args:
509
+ for param_idx, param in enumerate(func_args.args):
510
+ param_name = param.arg
511
+ param_var = state.get_variable(
512
+ callee_scope,
513
+ call_context,
514
+ solver.variable_factory.make_variable(param_name)
515
+ )
516
+
517
+ # First check if this parameter is provided as a keyword argument
518
+ if param_name in kwarg_vars:
519
+ # Bind keyword argument to parameter
520
+ state._add_var_points_flow(kwarg_vars[param_name], param_var)
521
+ consumed_kwargs.add(param_name)
522
+ elif arg_index < len(arg_vars):
523
+ # Bind positional argument to parameter
524
+ state._add_var_points_flow(arg_vars[arg_index], param_var)
525
+ arg_index += 1
526
+ else:
527
+ default_entry = positional_defaults.get(param_name)
528
+ if default_entry is not None:
529
+ default_expr, default_idx = default_entry
530
+ def_scope = callee_obj.container_scope
531
+ def_context = def_scope.context
532
+ default_ctx = self._materialize_default(
533
+ solver=solver,
534
+ func_ir=func_ir,
535
+ def_scope=def_scope,
536
+ def_context=def_context,
537
+ param_name=param_name,
538
+ default_index=default_idx,
539
+ default_expr=default_expr,
540
+ )
541
+ state._add_var_points_flow(default_ctx, param_var)
542
+ else:
543
+ # Missing required parameter - this is an error in real Python
544
+ solver._unknown_tracker.record(
545
+ UnknownKind.MISSING_ARGUMENT,
546
+ str(call.call_site),
547
+ f"Required parameter {param_name} not provided",
548
+ context=func_name
549
+ )
550
+
551
+ # 3. Handle *args (vararg) - collects remaining positional arguments
552
+ if func_args.vararg:
553
+ vararg_name = func_args.vararg.arg
554
+ vararg_var = state.get_variable(
555
+ callee_scope,
556
+ call_context,
557
+ solver.variable_factory.make_variable(vararg_name)
558
+ )
559
+
560
+ # Create a tuple object to hold the varargs
561
+ vararg_alloc = AllocSite(f"{call.call_site}:*args", AllocKind.TUPLE)
562
+ vararg_tuple_obj = TupleObject(call_context, vararg_alloc)
563
+
564
+ # Add the tuple to the vararg parameter
565
+ solver.handle_new_points_to(vararg_var, callee_scope, PointsToSet.singleton(vararg_tuple_obj))
566
+
567
+ # All remaining positional arguments go into *args
568
+ for i in range(arg_index, len(arg_vars)):
569
+ # Store each remaining argument as an element of the tuple
570
+ field = key(i - arg_index)
571
+ element_var = state.get_field(callee_scope, call_context, vararg_tuple_obj, field)
572
+ state._add_var_points_flow(arg_vars[i], element_var)
573
+ elif arg_index < len(arg_vars):
574
+ # Too many positional arguments and no *args to catch them
575
+ solver._unknown_tracker.record(
576
+ UnknownKind.MISSING_ARGUMENT,
577
+ str(call.call_site),
578
+ f"Too many positional arguments: expected {arg_index}, got {len(arg_vars)}",
579
+ context=func_name
580
+ )
581
+
582
+ # 4. Handle keyword-only parameters
583
+ # These MUST be provided by keyword arguments (or use defaults)
584
+ if func_args.kwonlyargs:
585
+ for kw_idx, param in enumerate(func_args.kwonlyargs):
586
+ param_name = param.arg
587
+ param_var = state.get_variable(
588
+ callee_scope,
589
+ call_context,
590
+ solver.variable_factory.make_variable(param_name)
591
+ )
592
+
593
+ # Check if provided as keyword argument
594
+ if param_name in kwarg_vars:
595
+ # Bind keyword argument to parameter
596
+ state._add_var_points_flow(kwarg_vars[param_name], param_var)
597
+ consumed_kwargs.add(param_name)
598
+ elif func_args.kw_defaults and kw_idx < len(func_args.kw_defaults):
599
+ # Check if there's a default value
600
+ kw_default = func_args.kw_defaults[kw_idx]
601
+ if kw_default is not None:
602
+ # Has a default value
603
+ def_scope = callee_obj.container_scope
604
+ def_context = def_scope.context
605
+ default_ctx = self._materialize_default(
606
+ solver=solver,
607
+ func_ir=func_ir,
608
+ def_scope=def_scope,
609
+ def_context=def_context,
610
+ param_name=param_name,
611
+ default_index=kw_idx,
612
+ default_expr=kw_default,
613
+ )
614
+ state._add_var_points_flow(default_ctx, param_var)
615
+ else:
616
+ # Missing required keyword-only parameter
617
+ solver._unknown_tracker.record(
618
+ UnknownKind.MISSING_ARGUMENT,
619
+ str(call.call_site),
620
+ f"Required keyword-only parameter {param_name} not provided",
621
+ context=func_name
622
+ )
623
+ else:
624
+ # Missing required keyword-only parameter with no default
625
+ solver._unknown_tracker.record(
626
+ UnknownKind.MISSING_ARGUMENT,
627
+ str(call.call_site),
628
+ f"Required keyword-only parameter {param_name} not provided",
629
+ context=func_name
630
+ )
631
+
632
+ # 5. Handle **kwargs (kwarg) - collects remaining keyword arguments
633
+ remaining_kwargs = {k: v for k, v in kwarg_vars.items() if k not in consumed_kwargs}
634
+
635
+ if func_args.kwarg:
636
+ kwarg_name = func_args.kwarg.arg
637
+ kwarg_var = state.get_variable(
638
+ callee_scope,
639
+ call_context,
640
+ solver.variable_factory.make_variable(kwarg_name)
641
+ )
642
+
643
+ # Create a dict object to hold the kwargs
644
+ kwarg_alloc = AllocSite(f"{call.call_site}:**kwargs", AllocKind.DICT)
645
+ kwarg_dict_obj = DictObject(call_context, kwarg_alloc)
646
+
647
+ # Add the dict to the kwarg parameter
648
+ solver.handle_new_points_to(kwarg_var, callee_scope, PointsToSet.singleton(kwarg_dict_obj))
649
+
650
+ # Store all remaining keyword arguments into the **kwargs dict
651
+ for kw_name, kw_var in remaining_kwargs.items():
652
+ # Use the keyword name as the dict key (field)
653
+ field = key(kw_name)
654
+ dict_value_var = state.get_field(callee_scope, call_context, kwarg_dict_obj, field)
655
+ state._add_var_points_flow(kw_var, dict_value_var)
656
+ elif remaining_kwargs:
657
+ # Unexpected keyword arguments and no **kwargs to catch them
658
+ extra_kw_names = ', '.join(remaining_kwargs.keys())
659
+ solver._unknown_tracker.record(
660
+ UnknownKind.MISSING_ARGUMENT,
661
+ str(call.call_site),
662
+ f"Unexpected keyword arguments: {extra_kw_names}",
663
+ context=func_name
664
+ )