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,132 @@
1
+ """Files that parsed with syntax errors, in every language (#73).
2
+
3
+ A plugin records the error line spans per file in its file report (`syntax_errors`: {path: [[first, last], ...]}):
4
+ tree-sitter ERROR / MISSING nodes (Swift, Kotlin, Rust, C / C++), the TypeScript parser's diagnostics, the Dart
5
+ analyzer's errors, the line of a Python / PHP parse failure. After indexing, `summarize` adds the declarations lost:
6
+ declaration heads (per-language patterns) inside the spans (the whole file for a file that failed to parse) whose
7
+ name the graph has no node for in that file. `cg coverage` lists the files with their spans and losses, and an answer
8
+ that touches such a file carries a partial-answer note."""
9
+ from __future__ import annotations
10
+
11
+ import re
12
+ from pathlib import Path
13
+
14
+ MAX_FILES = 500 # files stored per language (counts are always exact)
15
+ MAX_SPANS = 20 # spans stored per file
16
+ MAX_NAMES = 5 # lost declaration names stored per file
17
+
18
+ _SWIFT_MODS = (r"(?:(?:public|private|fileprivate|internal|open|package|static|final|override|mutating|nonmutating|"
19
+ r"nonisolated|isolated|required|convenience|dynamic|indirect|distributed|class(?=\s+func))\s+)*")
20
+ DECL = {
21
+ "swift": re.compile(r"^[ \t]*(?:@[\w.]+(?:\([^)\n]*\))?\s+)*" + _SWIFT_MODS +
22
+ r"(func|init|class|struct|enum|protocol|extension|actor)\b[ \t]*([A-Za-z_]\w*)?", re.M),
23
+ "kotlin": re.compile(r"^[ \t]*(?:@[\w.]+(?:\([^)\n]*\))?\s+)*(?:(?:public|private|internal|protected|open|abstract|"
24
+ r"override|suspend|inline|data|sealed|enum|annotation|inner|value|companion|actual|expect|"
25
+ r"operator|infix|tailrec|external)\s+)*(fun|class|interface|object)\b[ \t]*"
26
+ r"(?:<[^>\n]*>\s*)?(?:[\w.]+\.)?([A-Za-z_]\w*)?", re.M),
27
+ "rust": re.compile(r"^[ \t]*(?:pub(?:\([^)]*\))?\s+)?(?:(?:const|async|unsafe|extern\s+\"\w+\")\s+)*"
28
+ r"(fn|struct|enum|trait|mod|union)\s+([A-Za-z_]\w*)", re.M),
29
+ "c_cpp": re.compile(r"^(?:[\w:*&<>,~]+[ \t]+)*?(?:(class|struct)\s+([A-Za-z_]\w*)\s*(?::[^;{]*)?\{|"
30
+ r"()(?:[\w:<>]+::)?(~?[A-Za-z_]\w*)\s*\([^;{}]*\)\s*(?:const\s*)?(?:noexcept\s*)?\{)", re.M),
31
+ "typescript": re.compile(r"^[ \t]*(?:export\s+)?(?:default\s+)?(?:declare\s+)?(?:abstract\s+)?(?:async\s+)?"
32
+ r"(function\*?|class|interface|enum)\s+([A-Za-z_$][\w$]*)", re.M),
33
+ "python": re.compile(r"^[ \t]*(?:async\s+)?(def|class)\s+([A-Za-z_]\w*)", re.M),
34
+ "php": re.compile(r"^[ \t]*(?:(?:abstract|final|public|private|protected|static|readonly)\s+)*"
35
+ r"(function|class|interface|trait|enum)\s+&?([A-Za-z_]\w*)", re.M),
36
+ "dart": re.compile(r"^[ \t]*(?:(?:abstract|base|final|sealed|interface|mixin)\s+)*(class|mixin|enum|extension)\s+"
37
+ r"([A-Za-z_]\w*)", re.M),
38
+ }
39
+ NO_NODE = {"swift": {"deinit"}, "rust": set(), "c_cpp": {"if", "for", "while", "switch", "catch", "return", "sizeof"}}
40
+
41
+
42
+ def tree_spans(root) -> list[list[int]]:
43
+ """[first line, last line] (1-based) of the outermost ERROR nodes and of each MISSING node, merged."""
44
+ out = []
45
+ stack = [root]
46
+ while stack:
47
+ n = stack.pop()
48
+ if n.type == "ERROR":
49
+ if n.start_byte == n.end_byte and n.next_sibling is not None and n.next_sibling.type == "directive":
50
+ continue # tree-sitter-swift's empty ERROR before an `#if` between members: nothing lost
51
+ out.append([n.start_point[0] + 1, max(n.end_point[0] + 1 - (n.end_point[1] == 0 and
52
+ n.end_point[0] > n.start_point[0]), n.start_point[0] + 1)])
53
+ continue
54
+ if n.is_missing:
55
+ out.append([n.start_point[0] + 1, n.start_point[0] + 1])
56
+ continue
57
+ if n.has_error:
58
+ stack.extend(n.children)
59
+ return merge(out)
60
+
61
+
62
+ def merge(spans) -> list[list[int]]:
63
+ out: list[list[int]] = []
64
+ for a, b in sorted([int(x), int(y)] for x, y in spans):
65
+ if out and a <= out[-1][1] + 1:
66
+ out[-1][1] = max(out[-1][1], b)
67
+ else:
68
+ out.append([a, b])
69
+ return out
70
+
71
+
72
+ def _decls(lang: str, text: str, spans) -> list[tuple[int, str]]:
73
+ """(line, name) of the declaration heads inside the spans."""
74
+ rx = DECL.get(lang)
75
+ if rx is None or not spans:
76
+ return []
77
+ starts = [0]
78
+ for m in re.finditer("\n", text):
79
+ starts.append(m.end())
80
+ import bisect
81
+ out = []
82
+ for m in rx.finditer(text):
83
+ kw = next((g for g in m.groups()[0::2] if g is not None), "")
84
+ name = next((g for g in m.groups()[1::2] if g), None) or (kw if kw == "init" else None)
85
+ if not name or name in NO_NODE.get(lang, ()) or (lang == "swift" and kw == "extension"):
86
+ continue # a Swift extension has no node of its own (the type's may be in another file); its members count
87
+ if lang == "c_cpp" and not kw and name.upper() == name:
88
+ continue # `TEST_IMPL(poll_duplex) {`: a macro that expands to a definition, not a function name
89
+ ln = bisect.bisect_right(starts, m.start(m.lastindex) if m.lastindex else m.start())
90
+ if any(a <= ln <= b for a, b in spans):
91
+ out.append((ln, name))
92
+ return out
93
+
94
+
95
+ def summarize(lang: str, root: Path, raw: dict, names_by_file: dict, failed=()) -> list[dict]:
96
+ """[{file, spans, errors, decls_lost, lost}] for the files of one language, most declarations lost first."""
97
+ failed = set(failed or ())
98
+ out = []
99
+ for rel, spans in raw.items():
100
+ spans = merge(spans or [])
101
+ if not spans and rel not in failed:
102
+ continue
103
+ try:
104
+ text = (Path(root) / rel).read_bytes().decode("utf-8", "replace")
105
+ except OSError:
106
+ text = ""
107
+ whole = [[1, text.count("\n") + 1]] if rel in failed else spans
108
+ have = names_by_file.get(rel, set())
109
+ lost = [(ln, nm) for ln, nm in _decls(lang, text, whole) if nm not in have]
110
+ e = {"file": rel, "spans": spans[:MAX_SPANS], "errors": len(spans), "decls_lost": len(lost)}
111
+ if lost:
112
+ e["lost"] = [f"{nm}:{ln}" for ln, nm in lost[:MAX_NAMES]]
113
+ if rel in failed:
114
+ e["parse_failed"] = True
115
+ out.append(e)
116
+ out.sort(key=lambda e: (-e["decls_lost"], e["file"]))
117
+ return out
118
+
119
+
120
+ def span_text(e: dict, limit: int = 3) -> str:
121
+ """'Sources/A.swift:83-90, 120 (2 declarations lost: loads:85, testAfter:88)'."""
122
+ sp = e.get("spans") or []
123
+ pos = ", ".join(f"{a}" if a == b else f"{a}-{b}" for a, b in sp[:limit]) + (f" +{e['errors'] - limit}" if e.get("errors", 0) > limit else "")
124
+ s = f"{e['file']}:{pos}" if pos else e["file"]
125
+ n = e.get("decls_lost", 0)
126
+ if e.get("parse_failed"):
127
+ s += " (parse failed"
128
+ s += f", {n} declaration{'s' if n != 1 else ''} lost" if n else ""
129
+ return s + ")"
130
+ if n:
131
+ s += f" ({n} declaration{'s' if n != 1 else ''} lost: {', '.join(e.get('lost') or [])}" + (" …" if n > len(e.get("lost") or []) else "") + ")"
132
+ return s