pviz-parser 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.
- adapters/__init__.py +0 -0
- adapters/analyzer_bridge/__init__.py +26 -0
- adapters/analyzer_bridge/bridge_payloads.py +259 -0
- adapters/analyzer_bridge/core.py +668 -0
- adapters/analyzer_bridge/internals.py +260 -0
- adapters/analyzer_bridge/provenance.py +135 -0
- adapters/canonical.py +340 -0
- adapters/payloads.py +253 -0
- analyzer/__init__.py +172 -0
- analyzer/analyzer_types.py +216 -0
- analyzer/ast_common.py +1098 -0
- analyzer/build_classic.py +373 -0
- analyzer/config.py +288 -0
- analyzer/dead_code.py +635 -0
- analyzer/discovery_manifest.py +936 -0
- analyzer/duplicate_code.py +400 -0
- analyzer/extract_crosstalk.py +414 -0
- analyzer/followup_python.py +0 -0
- analyzer/fs.py +259 -0
- analyzer/go/__init__.py +26 -0
- analyzer/go/go_build_artifacts.py +614 -0
- analyzer/go/go_canonical.py +315 -0
- analyzer/go/go_config.py +155 -0
- analyzer/go/go_folder_index.py +976 -0
- analyzer/go/go_nodefacts_symbols.py +172 -0
- analyzer/go/go_parse.py +319 -0
- analyzer/go/go_parse_dispatch.py +284 -0
- analyzer/go/go_run.py +535 -0
- analyzer/imports_lex.py +167 -0
- analyzer/index.py +428 -0
- analyzer/java/__init__.py +0 -0
- analyzer/java/java_build_artifacts.py +1164 -0
- analyzer/java/java_canonical.py +329 -0
- analyzer/java/java_config.py +75 -0
- analyzer/java/java_folder_index.py +1142 -0
- analyzer/java/java_nodefacts_symbols.py +445 -0
- analyzer/java/java_parse/__init__.py +19 -0
- analyzer/java/java_parse/engine.py +48 -0
- analyzer/java/java_parse/javaparser_engine.py +336 -0
- analyzer/java/java_parse/models.py +58 -0
- analyzer/java/java_parse/regex_engine.py +372 -0
- analyzer/java/java_parse_dispatch.py +238 -0
- analyzer/java/java_run.py +488 -0
- analyzer/kotlin/__init__.py +1 -0
- analyzer/kotlin/kotlin_build_artifacts.py +508 -0
- analyzer/kotlin/kotlin_canonical.py +147 -0
- analyzer/kotlin/kotlin_config.py +37 -0
- analyzer/kotlin/kotlin_folder_index.py +1144 -0
- analyzer/kotlin/kotlin_nodefacts_symbols.py +123 -0
- analyzer/kotlin/kotlin_parse_dispatch.py +20 -0
- analyzer/kotlin/kotlin_run.py +299 -0
- analyzer/kotlin/parse_kotlin/__init__.py +15 -0
- analyzer/kotlin/parse_kotlin/engine.py +104 -0
- analyzer/kotlin/parse_kotlin/models.py +143 -0
- analyzer/l2_method_usage.py +196 -0
- analyzer/module_map.py +170 -0
- analyzer/module_resolve.py +420 -0
- analyzer/parse.py +306 -0
- analyzer/py/__init__.py +0 -0
- analyzer/py/py_run.py +120 -0
- analyzer/rust/__init__.py +0 -0
- analyzer/rust/rust_build_artifacts.py +1347 -0
- analyzer/rust/rust_canonical.py +392 -0
- analyzer/rust/rust_config.py +133 -0
- analyzer/rust/rust_folder_index.py +1234 -0
- analyzer/rust/rust_nodefacts_symbols.py +483 -0
- analyzer/rust/rust_parse/__init__.py +44 -0
- analyzer/rust/rust_parse/engine.py +282 -0
- analyzer/rust/rust_parse/models.py +438 -0
- analyzer/rust/rust_parse_dispatch.py +218 -0
- analyzer/rust/rust_run.py +489 -0
- analyzer/ts/__init__.py +7 -0
- analyzer/ts/build_artifacts.py +690 -0
- analyzer/ts/canonical_web.py +422 -0
- analyzer/ts/config.py +53 -0
- analyzer/ts/discover.py +54 -0
- analyzer/ts/extract_crosstalk.py +344 -0
- analyzer/ts/extract_imports.py +188 -0
- analyzer/ts/model.py +24 -0
- analyzer/ts/parser_runtime.py +91 -0
- analyzer/ts/resolve_imports.py +266 -0
- analyzer/ts/run.py +979 -0
- analyzer/ts/symbols_js.py +319 -0
- analyzer/ts/tsconfig_paths.py +548 -0
- analyzer/ts/write_artifacts.py +12 -0
- analyzer_store/__init__.py +1 -0
- analyzer_store/coverage.py +73 -0
- analyzer_store/edge_pass.py +536 -0
- analyzer_store/folder_index.py +931 -0
- analyzer_store/followup_assess.py +50 -0
- analyzer_store/integration.py +727 -0
- analyzer_store/io_utils.py +128 -0
- analyzer_store/nodefacts.py +1256 -0
- analyzer_store/types.py +138 -0
- analyzer_store/validators.py +72 -0
- contracts/__init__.py +0 -0
- contracts/types.py +184 -0
- core/artifact_sets_merge/__init__.py +5 -0
- core/artifact_sets_merge/api.py +176 -0
- core/artifact_sets_merge/config.py +86 -0
- core/artifact_sets_merge/crosstalk.py +225 -0
- core/artifact_sets_merge/discovery.py +44 -0
- core/artifact_sets_merge/edges.py +53 -0
- core/artifact_sets_merge/folder_index.py +125 -0
- core/artifact_sets_merge/io.py +52 -0
- core/artifact_sets_merge/meta.py +112 -0
- core/artifact_sets_merge/metrics.py +115 -0
- core/artifact_sets_merge/nodes.py +205 -0
- core/artifact_sets_merge/normalize.py +33 -0
- core/artifact_sets_merge/publish.py +156 -0
- core/artifact_sets_merge/scc.py +245 -0
- core/artifacts.py +204 -0
- core/artifacts_headless.py +50 -0
- core/build_context.py +91 -0
- core/build_pipeline/JS_P_Crosstalk.py +845 -0
- core/build_pipeline/P_JS_Crosstalk.py +1023 -0
- core/build_pipeline/__init__.py +32 -0
- core/build_pipeline/buckets.py +955 -0
- core/build_pipeline/followups.py +108 -0
- core/build_pipeline/json_io.py +18 -0
- core/build_pipeline/normalize.py +82 -0
- core/build_pipeline/pipeline.py +556 -0
- core/build_pipeline/types.py +87 -0
- core/json_export.py +541 -0
- core/pkgzones/builder.py +437 -0
- core/pkgzones/contracts.py +91 -0
- core/pkgzones/placement.py +114 -0
- core/pkgzones/state.py +32 -0
- core/store_root.py +79 -0
- core/workspace_core.py +150 -0
- core/zones_ctx.py +313 -0
- core/zones_headless.py +71 -0
- diagnostics/__init__.py +0 -0
- diagnostics/events.py +52 -0
- diagnostics/logging.py +360 -0
- i_o/__init__.py +55 -0
- i_o/diagnostics_export.py +51 -0
- i_o/export_json.py +361 -0
- i_o/export_llm_json/__init__.py +4 -0
- i_o/export_llm_json/artifacts.py +65 -0
- i_o/export_llm_json/builders_discovery.py +119 -0
- i_o/export_llm_json/builders_folders.py +356 -0
- i_o/export_llm_json/builders_node_order.py +15 -0
- i_o/export_llm_json/builders_nodes_edges.py +251 -0
- i_o/export_llm_json/builders_zones.py +41 -0
- i_o/export_llm_json/errors.py +5 -0
- i_o/export_llm_json/export.py +573 -0
- i_o/export_llm_json/json_compression/__init__.py +16 -0
- i_o/export_llm_json/json_compression/edge_codecs.py +157 -0
- i_o/export_llm_json/json_compression/format_guide.py +215 -0
- i_o/export_llm_json/json_compression/node_codecs.py +328 -0
- i_o/export_llm_json/json_compression/nodes.py +165 -0
- i_o/export_llm_json/json_compression/path_legend.py +230 -0
- i_o/export_llm_json/json_compression/run.py +136 -0
- i_o/export_llm_json/json_compression/types.py +130 -0
- i_o/export_llm_json/json_compression/util.py +60 -0
- i_o/export_llm_json/summary.py +649 -0
- i_o/export_llm_json/utils.py +62 -0
- i_o/export_pdf.py +97 -0
- i_o/layout_store.py +455 -0
- i_o/path_utils.py +23 -0
- i_o/workspace_io.py +295 -0
- i_o/workspace_manager.py +171 -0
- pviz_parser-0.1.0.dist-info/METADATA +123 -0
- pviz_parser-0.1.0.dist-info/RECORD +169 -0
- pviz_parser-0.1.0.dist-info/WHEEL +5 -0
- pviz_parser-0.1.0.dist-info/entry_points.txt +2 -0
- pviz_parser-0.1.0.dist-info/licenses/LICENSE +21 -0
- pviz_parser-0.1.0.dist-info/top_level.txt +7 -0
adapters/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# adapters/analyzer_bridge/__init__.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Any, Dict, Optional
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from .core import normalize_graph_for_contracts as normalize_graph_for_contracts
|
|
8
|
+
__all__ = [
|
|
9
|
+
"normalize_graph_for_contracts",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
def enrich_graph(graph: Any, *, repo_root: Optional[Path | str] = None) -> Dict[str, Any]:
|
|
13
|
+
g = graph if isinstance(graph, dict) else {"nodes": {}, "edges": []}
|
|
14
|
+
nodes = g.get("nodes") or {}
|
|
15
|
+
for _id, payload in nodes.items():
|
|
16
|
+
if not isinstance(payload, dict):
|
|
17
|
+
continue
|
|
18
|
+
defs_rows = payload.get("defs_rows") or []
|
|
19
|
+
extra = payload.setdefault("extra", {})
|
|
20
|
+
if "defs_rows" not in extra:
|
|
21
|
+
extra["defs_rows"] = list(defs_rows)
|
|
22
|
+
return g
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Backward-compatible alias
|
|
26
|
+
enrich_for_ui = enrich_graph
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Dict, List, Optional, Sequence
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from .internals import build_import_row_annotations
|
|
7
|
+
from adapters.canonical import (
|
|
8
|
+
repo_rel,
|
|
9
|
+
to_posix,
|
|
10
|
+
canon_file_id,
|
|
11
|
+
canon_module_id,
|
|
12
|
+
)
|
|
13
|
+
from adapters.analyzer_bridge.internals import (
|
|
14
|
+
as_list,
|
|
15
|
+
attr_or_key,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _dedupe_preserve_order(seq: Sequence[str]) -> List[str]:
|
|
20
|
+
seen: set[str] = set()
|
|
21
|
+
out: List[str] = []
|
|
22
|
+
for s in seq:
|
|
23
|
+
if s not in seen:
|
|
24
|
+
seen.add(s)
|
|
25
|
+
out.append(s)
|
|
26
|
+
return out
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _to_name(v) -> Optional[str]:
|
|
30
|
+
if v is None:
|
|
31
|
+
return None
|
|
32
|
+
if isinstance(v, str):
|
|
33
|
+
s = v.strip()
|
|
34
|
+
if s.startswith(("def ", "class ")):
|
|
35
|
+
s = s.split(" ", 1)[1].strip() or s
|
|
36
|
+
return s or None
|
|
37
|
+
if isinstance(v, dict):
|
|
38
|
+
name = v.get("name") or v.get("label") or v.get("id")
|
|
39
|
+
return str(name) if name else None
|
|
40
|
+
for attr in ("name", "label", "id"):
|
|
41
|
+
try:
|
|
42
|
+
name = getattr(v, attr, None)
|
|
43
|
+
if isinstance(name, str) and name:
|
|
44
|
+
return name
|
|
45
|
+
except Exception:
|
|
46
|
+
pass
|
|
47
|
+
try:
|
|
48
|
+
s = str(v)
|
|
49
|
+
if s and s != "(none)":
|
|
50
|
+
return s
|
|
51
|
+
except Exception:
|
|
52
|
+
pass
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _clean_and_normalize_import_rows(rows_like) -> List[str]:
|
|
57
|
+
out: List[str] = []
|
|
58
|
+
for r in as_list(rows_like):
|
|
59
|
+
s = r if isinstance(r, str) else _to_name(r) or ""
|
|
60
|
+
s = (s or "").strip()
|
|
61
|
+
if not s:
|
|
62
|
+
continue
|
|
63
|
+
# strip trailing comments
|
|
64
|
+
i = s.find("#")
|
|
65
|
+
if i == 0:
|
|
66
|
+
continue
|
|
67
|
+
if i > 0:
|
|
68
|
+
s = s[:i].rstrip()
|
|
69
|
+
if not s:
|
|
70
|
+
continue
|
|
71
|
+
if s.startswith("from ") or s.startswith("import "):
|
|
72
|
+
out.append(s)
|
|
73
|
+
else:
|
|
74
|
+
out.append(f"import {s}")
|
|
75
|
+
return _dedupe_preserve_order(out)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def node_payload_from(node_id: str, n: Any, *, repo_root: Optional[Path | str]) -> Dict[str, Any]:
|
|
79
|
+
"""
|
|
80
|
+
Authoritative payload builder used by analyzer.
|
|
81
|
+
|
|
82
|
+
Assumptions under the current contracts:
|
|
83
|
+
- `node_id` is a stable node identifier; for analyzer-backed graphs this
|
|
84
|
+
is a **module id** relative to the scan root (e.g. 'downloader',
|
|
85
|
+
'scrapy.core.engine', 'ui.app.run_gui').
|
|
86
|
+
- The node record `n` may carry:
|
|
87
|
+
• path/file: repo-relative or absolute path
|
|
88
|
+
• module: dotted module id
|
|
89
|
+
"""
|
|
90
|
+
root = to_posix(str(repo_root)) if repo_root else None
|
|
91
|
+
|
|
92
|
+
# ---------- Canonical file-id (repo-rel POSIX) ----------
|
|
93
|
+
# Prefer an explicit path/file on the node; fall back to id/module when needed.
|
|
94
|
+
raw_path_like = (
|
|
95
|
+
attr_or_key(n, "path")
|
|
96
|
+
or attr_or_key(n, "file")
|
|
97
|
+
or (str(node_id) if isinstance(node_id, str) else "")
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
canon_path = ""
|
|
101
|
+
try:
|
|
102
|
+
# canon_file_id knows how to handle both path-ish and dotted inputs;
|
|
103
|
+
# we pass scan_root so it will keep things repo-relative when possible.
|
|
104
|
+
canon_path = canon_file_id(raw_path_like, root, strict_suffix=False) or ""
|
|
105
|
+
except Exception:
|
|
106
|
+
canon_path = ""
|
|
107
|
+
|
|
108
|
+
if not canon_path:
|
|
109
|
+
# Retry from explicit module field if present
|
|
110
|
+
raw_mod = attr_or_key(n, "module") or ""
|
|
111
|
+
try:
|
|
112
|
+
if raw_mod:
|
|
113
|
+
canon_path = canon_file_id(raw_mod, root, strict_suffix=False) or ""
|
|
114
|
+
except Exception:
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
canon_path = to_posix(canon_path) if canon_path else ""
|
|
118
|
+
|
|
119
|
+
# ---------- Canonical module (dotted) ----------
|
|
120
|
+
# Prefer node_id itself when it behaves like a module id (no slashes, no .py).
|
|
121
|
+
module = ""
|
|
122
|
+
if isinstance(node_id, str):
|
|
123
|
+
nid = node_id.strip()
|
|
124
|
+
if nid and "/" not in nid and "\\" not in nid and not nid.endswith(".py"):
|
|
125
|
+
module = nid
|
|
126
|
+
|
|
127
|
+
if not module and canon_path:
|
|
128
|
+
try:
|
|
129
|
+
module = canon_module_id(canon_path, root) or ""
|
|
130
|
+
except Exception:
|
|
131
|
+
module = ""
|
|
132
|
+
|
|
133
|
+
if not module:
|
|
134
|
+
raw_mod = attr_or_key(n, "module") or ""
|
|
135
|
+
try:
|
|
136
|
+
if raw_mod:
|
|
137
|
+
module = canon_module_id(raw_mod, root) or ""
|
|
138
|
+
except Exception:
|
|
139
|
+
# last resort: try making a module from the raw path-ish
|
|
140
|
+
try:
|
|
141
|
+
module = canon_module_id(raw_path_like, root) if raw_path_like else ""
|
|
142
|
+
except Exception:
|
|
143
|
+
module = ""
|
|
144
|
+
|
|
145
|
+
# ---------- Header path for UI (repo-rel POSIX) ----------
|
|
146
|
+
header_path = canon_path or repo_rel(
|
|
147
|
+
attr_or_key(n, "path") or attr_or_key(n, "file"),
|
|
148
|
+
repo_root,
|
|
149
|
+
)
|
|
150
|
+
if isinstance(header_path, str):
|
|
151
|
+
header_path = to_posix(header_path)
|
|
152
|
+
|
|
153
|
+
# ---------- Label: prefer module leaf; fall back to basename ----------
|
|
154
|
+
if module:
|
|
155
|
+
label = module.split(".")[-1]
|
|
156
|
+
else:
|
|
157
|
+
leaf = to_posix(str(header_path or node_id))
|
|
158
|
+
label = os.path.basename(leaf.rstrip("/")) if leaf else str(node_id)
|
|
159
|
+
|
|
160
|
+
# ---------- Imports ----------
|
|
161
|
+
pre_rows = attr_or_key(n, "imports_rows") or (
|
|
162
|
+
(attr_or_key(n, "extra") or {}).get("imports_rows")
|
|
163
|
+
if isinstance(n, dict)
|
|
164
|
+
else None
|
|
165
|
+
)
|
|
166
|
+
raw_imports = attr_or_key(n, "imports")
|
|
167
|
+
imp_rows = (
|
|
168
|
+
_clean_and_normalize_import_rows(pre_rows)
|
|
169
|
+
if pre_rows
|
|
170
|
+
else _clean_and_normalize_import_rows(raw_imports)
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# Fallback: mine file only if still empty
|
|
174
|
+
if not imp_rows:
|
|
175
|
+
try:
|
|
176
|
+
abs_hint = attr_or_key(n, "file") or attr_or_key(n, "path") or ""
|
|
177
|
+
p: Optional[str] = None
|
|
178
|
+
if isinstance(abs_hint, str) and os.path.isabs(abs_hint):
|
|
179
|
+
p = abs_hint
|
|
180
|
+
elif isinstance(canon_path, str) and canon_path:
|
|
181
|
+
p = str(Path(root) / canon_path) if root else None
|
|
182
|
+
if p and p.endswith(".py") and os.path.exists(p):
|
|
183
|
+
with open(p, "r", encoding="utf-8", errors="ignore") as f:
|
|
184
|
+
text = f.read(64_000)
|
|
185
|
+
lines = (ln.strip() for ln in text.splitlines())
|
|
186
|
+
imp_rows = [
|
|
187
|
+
s
|
|
188
|
+
for s in lines
|
|
189
|
+
if s
|
|
190
|
+
and not s.startswith("#")
|
|
191
|
+
and (s.startswith("import ") or (s.startswith("from ") and " import " in s))
|
|
192
|
+
]
|
|
193
|
+
imp_rows = _dedupe_preserve_order(imp_rows)
|
|
194
|
+
except Exception:
|
|
195
|
+
pass
|
|
196
|
+
|
|
197
|
+
# ---------- Defs / exports ----------
|
|
198
|
+
pre_defs = attr_or_key(n, "defs_rows") or (
|
|
199
|
+
(attr_or_key(n, "extra") or {}).get("defs_rows")
|
|
200
|
+
if isinstance(n, dict)
|
|
201
|
+
else None
|
|
202
|
+
)
|
|
203
|
+
classes = _dedupe_preserve_order(as_list(attr_or_key(n, "classes")))
|
|
204
|
+
functions = _dedupe_preserve_order(as_list(attr_or_key(n, "functions")))
|
|
205
|
+
globals_ = _dedupe_preserve_order(as_list(attr_or_key(n, "globals")))
|
|
206
|
+
raw_exports = attr_or_key(n, "exports")
|
|
207
|
+
|
|
208
|
+
if pre_defs:
|
|
209
|
+
def_rows = [
|
|
210
|
+
s
|
|
211
|
+
for s in _dedupe_preserve_order(as_list(pre_defs))
|
|
212
|
+
if s and s != "(none)"
|
|
213
|
+
]
|
|
214
|
+
else:
|
|
215
|
+
seen: set[str] = set()
|
|
216
|
+
acc: List[str] = []
|
|
217
|
+
for s in [*classes, *functions, *globals_]:
|
|
218
|
+
if s not in seen:
|
|
219
|
+
seen.add(s)
|
|
220
|
+
acc.append(s)
|
|
221
|
+
def_rows = acc or ["(none)"]
|
|
222
|
+
|
|
223
|
+
parsed_for_tags = attr_or_key(n, "parsed")
|
|
224
|
+
import_rows_annotated, import_tag_counts = build_import_row_annotations(
|
|
225
|
+
imp_rows,
|
|
226
|
+
parsed_for_tags,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
extra: Dict[str, Any] = {
|
|
230
|
+
"imports": imp_rows,
|
|
231
|
+
"imports_rows": imp_rows,
|
|
232
|
+
"imports_display": [a.get("row") for a in import_rows_annotated]
|
|
233
|
+
if import_rows_annotated
|
|
234
|
+
else imp_rows,
|
|
235
|
+
"defs_rows": def_rows,
|
|
236
|
+
"import_rows_annotated": import_rows_annotated,
|
|
237
|
+
"import_tag_counts": import_tag_counts,
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# ---------- Final payload ----------
|
|
241
|
+
payload: Dict[str, Any] = {
|
|
242
|
+
"node_id": node_id,
|
|
243
|
+
"label": label,
|
|
244
|
+
"kind": "file",
|
|
245
|
+
"path": header_path or "",
|
|
246
|
+
"module": module or None,
|
|
247
|
+
"package": None,
|
|
248
|
+
"file": header_path or "",
|
|
249
|
+
"extra": extra,
|
|
250
|
+
"imports": imp_rows,
|
|
251
|
+
"imports_rows": imp_rows,
|
|
252
|
+
"imports_display": extra["imports_display"],
|
|
253
|
+
"defs_rows": def_rows,
|
|
254
|
+
"classes": classes,
|
|
255
|
+
"functions": functions,
|
|
256
|
+
"globals": globals_,
|
|
257
|
+
"exports": [e for e in as_list(raw_exports) if isinstance(e, str)],
|
|
258
|
+
}
|
|
259
|
+
return {k: v for k, v in payload.items() if v is not None}
|