cg-code-graph 0.10.1__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 (174) hide show
  1. cg_code_graph-0.10.1.dist-info/METADATA +678 -0
  2. cg_code_graph-0.10.1.dist-info/RECORD +174 -0
  3. cg_code_graph-0.10.1.dist-info/WHEEL +5 -0
  4. cg_code_graph-0.10.1.dist-info/entry_points.txt +3 -0
  5. cg_code_graph-0.10.1.dist-info/licenses/LICENSE +21 -0
  6. cg_code_graph-0.10.1.dist-info/top_level.txt +1 -0
  7. codegraph/__init__.py +2 -0
  8. codegraph/aitools.py +129 -0
  9. codegraph/apps.py +76 -0
  10. codegraph/blindspots.py +428 -0
  11. codegraph/bridges.py +1701 -0
  12. codegraph/cli.py +725 -0
  13. codegraph/concepts.py +362 -0
  14. codegraph/config.py +559 -0
  15. codegraph/core/__init__.py +0 -0
  16. codegraph/core/cache.py +375 -0
  17. codegraph/core/detect.py +80 -0
  18. codegraph/core/extractors.py +187 -0
  19. codegraph/core/fsutil.py +61 -0
  20. codegraph/core/generated.py +575 -0
  21. codegraph/core/model.py +174 -0
  22. codegraph/core/paths.py +175 -0
  23. codegraph/core/plugin.py +160 -0
  24. codegraph/core/store.py +80 -0
  25. codegraph/core/syntax_errors.py +132 -0
  26. codegraph/coverage.py +928 -0
  27. codegraph/doctor.py +453 -0
  28. codegraph/external.py +613 -0
  29. codegraph/indexer.py +336 -0
  30. codegraph/link.py +434 -0
  31. codegraph/lint_async.py +524 -0
  32. codegraph/mcp_server.py +1303 -0
  33. codegraph/parity.py +473 -0
  34. codegraph/parity_structure.py +307 -0
  35. codegraph/payload.py +321 -0
  36. codegraph/plans.py +1285 -0
  37. codegraph/platform_scan.py +643 -0
  38. codegraph/platforms.py +1369 -0
  39. codegraph/plugins/__init__.py +0 -0
  40. codegraph/plugins/cfamily/__init__.py +0 -0
  41. codegraph/plugins/cfamily/plugin.py +930 -0
  42. codegraph/plugins/cfamily/syntax.py +881 -0
  43. codegraph/plugins/dart/__init__.py +0 -0
  44. codegraph/plugins/dart/bridges.py +345 -0
  45. codegraph/plugins/dart/extractor/bin/extract.dart +717 -0
  46. codegraph/plugins/dart/extractor/pubspec.lock +149 -0
  47. codegraph/plugins/dart/extractor/pubspec.yaml +7 -0
  48. codegraph/plugins/dart/http.py +904 -0
  49. codegraph/plugins/dart/models.py +308 -0
  50. codegraph/plugins/dart/plugin.py +625 -0
  51. codegraph/plugins/dart/program.py +907 -0
  52. codegraph/plugins/django/__init__.py +0 -0
  53. codegraph/plugins/django/extras.py +378 -0
  54. codegraph/plugins/django/models.py +508 -0
  55. codegraph/plugins/django/plugin.py +728 -0
  56. codegraph/plugins/django/schemas.py +339 -0
  57. codegraph/plugins/django/shapes.py +216 -0
  58. codegraph/plugins/django/urls.py +603 -0
  59. codegraph/plugins/express/__init__.py +0 -0
  60. codegraph/plugins/express/plugin.py +428 -0
  61. codegraph/plugins/flutter/__init__.py +0 -0
  62. codegraph/plugins/flutter/plugin.py +538 -0
  63. codegraph/plugins/kotlin/__init__.py +0 -0
  64. codegraph/plugins/kotlin/exact.py +457 -0
  65. codegraph/plugins/kotlin/plugin.py +1961 -0
  66. codegraph/plugins/kotlin/reparse.py +234 -0
  67. codegraph/plugins/laravel/__init__.py +0 -0
  68. codegraph/plugins/laravel/broadcast.py +351 -0
  69. codegraph/plugins/laravel/plugin.py +863 -0
  70. codegraph/plugins/laravel/tests.py +262 -0
  71. codegraph/plugins/laravel/values.py +728 -0
  72. codegraph/plugins/native/__init__.py +0 -0
  73. codegraph/plugins/native/gates.py +286 -0
  74. codegraph/plugins/native/runner.py +183 -0
  75. codegraph/plugins/native/scipread.py +194 -0
  76. codegraph/plugins/native/ts.py +54 -0
  77. codegraph/plugins/nest/__init__.py +0 -0
  78. codegraph/plugins/nest/plugin.py +654 -0
  79. codegraph/plugins/nextjs/__init__.py +0 -0
  80. codegraph/plugins/nextjs/plugin.py +336 -0
  81. codegraph/plugins/nuxt/__init__.py +0 -0
  82. codegraph/plugins/nuxt/plugin.py +308 -0
  83. codegraph/plugins/php/__init__.py +0 -0
  84. codegraph/plugins/php/extractor/composer.json +5 -0
  85. codegraph/plugins/php/extractor/composer.lock +76 -0
  86. codegraph/plugins/php/extractor/extract.php +743 -0
  87. codegraph/plugins/php/gating.py +573 -0
  88. codegraph/plugins/php/plugin.py +668 -0
  89. codegraph/plugins/php/strings.py +197 -0
  90. codegraph/plugins/python/__init__.py +0 -0
  91. codegraph/plugins/python/aitools.py +664 -0
  92. codegraph/plugins/python/external.py +245 -0
  93. codegraph/plugins/python/fields.py +107 -0
  94. codegraph/plugins/python/plugin.py +1733 -0
  95. codegraph/plugins/python/refs.py +485 -0
  96. codegraph/plugins/python/roots.py +412 -0
  97. codegraph/plugins/python/socketio.py +210 -0
  98. codegraph/plugins/python/subproc.py +864 -0
  99. codegraph/plugins/python/tests.py +1040 -0
  100. codegraph/plugins/python/values.py +179 -0
  101. codegraph/plugins/pyweb/__init__.py +0 -0
  102. codegraph/plugins/pyweb/plugin.py +1334 -0
  103. codegraph/plugins/pyweb/values.py +68 -0
  104. codegraph/plugins/rust/__init__.py +0 -0
  105. codegraph/plugins/rust/cargo.py +226 -0
  106. codegraph/plugins/rust/plugin.py +980 -0
  107. codegraph/plugins/rust/syntax.py +678 -0
  108. codegraph/plugins/scip/__init__.py +0 -0
  109. codegraph/plugins/scip/importer.py +129 -0
  110. codegraph/plugins/scip/scip.proto +962 -0
  111. codegraph/plugins/scip/scip_pb2.py +97 -0
  112. codegraph/plugins/stubs/__init__.py +0 -0
  113. codegraph/plugins/stubs/plugins.py +38 -0
  114. codegraph/plugins/swift/__init__.py +0 -0
  115. codegraph/plugins/swift/baseurl.py +109 -0
  116. codegraph/plugins/swift/exact.py +415 -0
  117. codegraph/plugins/swift/indexstore.py +209 -0
  118. codegraph/plugins/swift/packages.py +174 -0
  119. codegraph/plugins/swift/plugin.py +2890 -0
  120. codegraph/plugins/ts/__init__.py +0 -0
  121. codegraph/plugins/ts/baseurl.py +185 -0
  122. codegraph/plugins/ts/extractor/extract.mjs +2652 -0
  123. codegraph/plugins/ts/extractor/fw.mjs +685 -0
  124. codegraph/plugins/ts/extractor/package-lock.json +205 -0
  125. codegraph/plugins/ts/extractor/package.json +9 -0
  126. codegraph/plugins/ts/plugin.py +480 -0
  127. codegraph/plugins/tsweb/__init__.py +0 -0
  128. codegraph/plugins/tsweb/common.py +290 -0
  129. codegraph/plugins/tsweb/data.py +276 -0
  130. codegraph/presets/__init__.py +146 -0
  131. codegraph/presets/c_cpp.yaml +9 -0
  132. codegraph/presets/common.yaml +66 -0
  133. codegraph/presets/dart.yaml +9 -0
  134. codegraph/presets/django-ninja.yaml +15 -0
  135. codegraph/presets/django.yaml +25 -0
  136. codegraph/presets/djangorestframework.yaml +17 -0
  137. codegraph/presets/express.yaml +17 -0
  138. codegraph/presets/kotlin.yaml +11 -0
  139. codegraph/presets/laravel.yaml +40 -0
  140. codegraph/presets/nest.yaml +11 -0
  141. codegraph/presets/nextjs.yaml +15 -0
  142. codegraph/presets/nuxt.yaml +9 -0
  143. codegraph/presets/php.yaml +5 -0
  144. codegraph/presets/python.yaml +10 -0
  145. codegraph/presets/rust.yaml +5 -0
  146. codegraph/presets/swift.yaml +10 -0
  147. codegraph/presets/typescript.yaml +13 -0
  148. codegraph/process_runs.py +328 -0
  149. codegraph/protocols/__init__.py +299 -0
  150. codegraph/protocols/builtin.py +67 -0
  151. codegraph/protocols/matchers.py +144 -0
  152. codegraph/protocols/view.py +334 -0
  153. codegraph/query.py +2089 -0
  154. codegraph/realtime.py +260 -0
  155. codegraph/roundtrip.py +346 -0
  156. codegraph/routes.py +442 -0
  157. codegraph/starters.py +218 -0
  158. codegraph/tests_index.py +117 -0
  159. codegraph/viz/__init__.py +0 -0
  160. codegraph/viz/graph.py +369 -0
  161. codegraph/viz/server.py +198 -0
  162. codegraph/viz/static/app.css +148 -0
  163. codegraph/viz/static/app.js +1082 -0
  164. codegraph/viz/static/index.html +81 -0
  165. codegraph/viz/static/layered.js +237 -0
  166. codegraph/viz/static/vendor/VERSIONS.txt +4 -0
  167. codegraph/viz/static/vendor/cose-base.js +3214 -0
  168. codegraph/viz/static/vendor/cytoscape-fcose.js +1549 -0
  169. codegraph/viz/static/vendor/cytoscape.min.js +31 -0
  170. codegraph/viz/static/vendor/layout-base.js +5230 -0
  171. codegraph/viz/tools/package-lock.json +303 -0
  172. codegraph/viz/tools/package.json +7 -0
  173. codegraph/viz/tools/shoot.mjs +165 -0
  174. codegraph/xcode.py +251 -0
@@ -0,0 +1,197 @@
1
+ """Static evaluation of PHP string expressions into name patterns.
2
+
3
+ Used for broadcast channel names (`"orders.{$this->order->id}"`, helper methods that build names, values passed
4
+ in at `new Event(...)` sites) and for URLs in HTTP tests. The result is a small set of patterns in which every
5
+ part that is unknown statically is a `{placeholder}`.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import itertools
10
+ import re
11
+
12
+ MAX_ALTS = 8
13
+ PH_RE = re.compile(r"\{[^{}]*\}")
14
+
15
+
16
+ def _short(d) -> str:
17
+ """Placeholder name for a dynamic expression: `$x` -> x, `$a->b->id` -> id, `$o->getKey()` -> key."""
18
+ if not d:
19
+ return "?"
20
+ k = d.get("k")
21
+ if k == "var":
22
+ return d.get("n") or "?"
23
+ if k in ("prop", "sprop"):
24
+ return d.get("n") or "?"
25
+ if k in ("mcall", "scall"):
26
+ m = d.get("m") or "?"
27
+ return m[3].lower() + m[4:] if m.startswith("get") and len(m) > 3 else m
28
+ if k == "dim" and (d.get("key") or {}).get("k") == "str":
29
+ return d["key"]["v"]
30
+ if k == "func":
31
+ a = d.get("args") or []
32
+ return _short(a[0]) if a else (d.get("n") or "?")
33
+ return "?"
34
+
35
+
36
+ class StrEval:
37
+ def __init__(self, prog):
38
+ self.prog = prog
39
+
40
+ def eval(self, d, fn, bind=None, depth=0) -> list[str]:
41
+ out = self._ev(d, fn, bind or {}, depth)
42
+ seen, res = set(), []
43
+ for s in out:
44
+ if s not in seen:
45
+ seen.add(s)
46
+ res.append(s)
47
+ return res[:MAX_ALTS]
48
+
49
+ def _prod(self, lists) -> list[str]:
50
+ out = []
51
+ for combo in itertools.product(*lists):
52
+ out.append("".join(combo))
53
+ if len(out) >= MAX_ALTS:
54
+ break
55
+ return out
56
+
57
+ def _ev(self, d, fn, bind, depth) -> list[str]:
58
+ if not d or depth > 10:
59
+ return ["{?}"]
60
+ k = d.get("k")
61
+ if k == "str":
62
+ return [d.get("v") or ""]
63
+ if k == "int":
64
+ return [str(d.get("v"))]
65
+ if k == "interp":
66
+ return self._prod([self._ev(p, fn, bind, depth + 1) for p in d.get("parts") or []])
67
+ if k == "concat":
68
+ return self._prod([self._ev(d.get("l"), fn, bind, depth + 1), self._ev(d.get("r"), fn, bind, depth + 1)])
69
+ if k == "alt":
70
+ out = []
71
+ for o in d.get("opts") or []:
72
+ out += self._ev(o, fn, bind, depth + 1)
73
+ return out[:MAX_ALTS]
74
+ if k == "var":
75
+ n = d.get("n")
76
+ if n in bind:
77
+ bd, bfn, bb = bind[n]
78
+ return self._ev(bd, bfn, bb, depth + 1)
79
+ assigns = [f for f in fn.facts if f.get("t") == "assign" and f.get("var") == n]
80
+ if 0 < len(assigns) <= 3:
81
+ out = []
82
+ for a in assigns:
83
+ out += self._ev(a["expr"], fn, {}, depth + 1)
84
+ return out[:MAX_ALTS]
85
+ return ["{" + (n or "?") + "}"]
86
+ if k == "prop":
87
+ if (d.get("of") or {}).get("k") == "this":
88
+ return ["{this." + (d.get("n") or "?") + "}"]
89
+ return ["{" + _short(d) + "}"]
90
+ if k == "const":
91
+ v = self.class_const(d.get("class"), d.get("n"))
92
+ return [str(v)] if isinstance(v, (str, int)) else ["{" + (d.get("n") or "?") + "}"]
93
+ if k in ("mcall", "scall", "func"):
94
+ r = self._call(d, fn, bind, depth)
95
+ if r is not None:
96
+ return r
97
+ return ["{" + _short(d) + "}"]
98
+ if k == "dim":
99
+ return ["{" + _short(d) + "}"]
100
+ return ["{?}"]
101
+
102
+ def class_const(self, cls, name):
103
+ if not cls or not name:
104
+ return None
105
+ for a in self.prog.ancestors(cls):
106
+ c = self.prog.cls(a)
107
+ if c:
108
+ for k in c.consts:
109
+ if k.get("name") == name:
110
+ return k.get("value")
111
+ return None
112
+
113
+ def _call(self, d, fn, bind, depth):
114
+ k = d.get("k")
115
+ args = d.get("args") or []
116
+ if k == "func":
117
+ n = (d.get("n") or "").lower().lstrip("\\")
118
+ if n in ("sprintf", "vsprintf") and args and args[0].get("k") == "str":
119
+ return self._sprintf(args[0]["v"], args[1:], fn, bind, depth)
120
+ if n in ("strtolower", "strtoupper", "trim", "strval", "str", "e") and args:
121
+ return self._ev(args[0], fn, bind, depth + 1)
122
+ if n == "implode" and len(args) == 2 and args[1].get("k") == "arr" and args[0].get("k") == "str":
123
+ lists = []
124
+ for j, it in enumerate(args[1].get("items") or []):
125
+ if j:
126
+ lists.append([args[0]["v"]])
127
+ lists.append(self._ev(it.get("v"), fn, bind, depth + 1))
128
+ return self._prod(lists) if lists else [""]
129
+ target = self.prog.functions.get(n)
130
+ elif k == "scall":
131
+ c = d.get("class")
132
+ target = self.prog.find_method(c, d.get("m")) if c and self.prog.cls(c) else None
133
+ else:
134
+ target = None
135
+ of = d.get("of") or {}
136
+ if of.get("k") == "this" and fn.cls:
137
+ target = self.prog.find_method(fn.cls, d.get("m"))
138
+ if not target or target.abstract:
139
+ return None
140
+ rets = [f for f in target.facts if f.get("t") == "return" and not f.get("ctx")]
141
+ if not rets:
142
+ return None
143
+ nb = {}
144
+ for i, p in enumerate(target.params):
145
+ a = next((x for x in args if x.get("named") == p["name"]), None)
146
+ if a is None and i < len(args) and not args[i].get("named"):
147
+ a = args[i]
148
+ if a is not None:
149
+ nb[p["name"]] = (a, fn, bind)
150
+ out = []
151
+ for r in rets[:4]:
152
+ out += self._ev(r["expr"], target, nb, depth + 1)
153
+ return out[:MAX_ALTS]
154
+
155
+ def _sprintf(self, fmt, args, fn, bind, depth):
156
+ pieces = re.split(r"(%(?:\d+\$)?[-+ 0']*\d*(?:\.\d+)?[sdfuxX])", fmt)
157
+ lists, i = [], 0
158
+ for p in pieces:
159
+ m = re.fullmatch(r"%(?:(\d+)\$)?[-+ 0']*\d*(?:\.\d+)?[sdfuxX]", p)
160
+ if m:
161
+ idx = int(m.group(1)) - 1 if m.group(1) else i
162
+ i += 1
163
+ lists.append(self._ev(args[idx], fn, bind, depth + 1) if idx < len(args) else ["{?}"])
164
+ else:
165
+ lists.append([p.replace("%%", "%")])
166
+ return self._prod(lists)
167
+
168
+
169
+ def pattern_regex(p: str) -> str:
170
+ out = []
171
+ for part in re.split(r"(\{[^{}]*\})", p):
172
+ if not part:
173
+ continue
174
+ out.append("[^.]+" if part.startswith("{") and part.endswith("}") else re.escape(part))
175
+ return "".join(out)
176
+
177
+
178
+ def concrete(p: str) -> str:
179
+ return PH_RE.sub("X", p)
180
+
181
+
182
+ def fully_dynamic(p: str) -> bool:
183
+ return not PH_RE.sub("", p).strip(". -_:/")
184
+
185
+
186
+ def same_shape(a: str, b: str) -> bool:
187
+ return PH_RE.sub("{}", a) == PH_RE.sub("{}", b)
188
+
189
+
190
+ def channel_match(name: str, declared: str) -> bool:
191
+ """A published / subscribed channel name (placeholders = runtime values) fits a declared channel pattern."""
192
+ if fully_dynamic(name):
193
+ return False
194
+ if re.fullmatch(pattern_regex(declared), concrete(name)):
195
+ return True
196
+ # a placeholder on the publishing side may itself stand for a dotted value (`{channel}`): try the reverse fit
197
+ return bool(re.fullmatch(pattern_regex(name), concrete(declared)))
File without changes