serpentine-parser 0.2.1__tar.gz → 0.3.0__tar.gz
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.
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/PKG-INFO +9 -7
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/README.md +6 -4
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/pyproject.toml +3 -3
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/Cargo.lock +95 -29
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/Cargo.toml +7 -6
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/graph/loaders.rs +18 -2
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/lib.rs +31 -11
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/python/mod.rs +107 -1
- serpentine_parser-0.3.0/rust/src/terraform/config.rs +47 -0
- serpentine_parser-0.3.0/rust/src/terraform/mod.rs +441 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/cli.py +57 -12
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/config.py +2 -2
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/skills/code-analysis.md +9 -1
- serpentine_parser-0.3.0/src/serpentine/static/assets/index-BPIIaXQj.js +219 -0
- serpentine_parser-0.3.0/src/serpentine/static/assets/index-DDwdNVWo.css +1 -0
- serpentine_parser-0.3.0/src/serpentine/static/assets/layoutWorker-BkzQvq4g.js +24 -0
- serpentine_parser-0.3.0/src/serpentine/static/assets/mermaidExport-B2JREVsY.js +3 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/static/index.html +2 -2
- serpentine_parser-0.2.1/src/serpentine/static/assets/index-BjdQg9Eg.js +0 -219
- serpentine_parser-0.2.1/src/serpentine/static/assets/index-Cwyiw9CD.css +0 -1
- serpentine_parser-0.2.1/src/serpentine/static/assets/layoutWorker-Dd3vNlDT.js +0 -24
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/LICENSE +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/CLAUDE.md +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/events.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/graph/builder.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/graph/mod.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/graph/pdg.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/graph/resolvers.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/javascript/config.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/javascript/mod.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/message_bus.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/python/config.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/rust_lang/config.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/rust_lang/mod.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/README.md +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/code_snippet.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/decorators.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/definitions.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/event_counter.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/imports.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/mod.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/pdg.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/raw_bindings.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/scope_tree.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/rust/src/subscribers/uses.rs +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/__init__.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/_analyzer.pyi +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/cache.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/selector.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/server/__init__.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/server/app.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/server/routes.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/server/websocket.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/skills/__init__.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/skills/agents-md.md +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/skills/copilot-instructions.md +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/skills/cursor-rules.md +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/state.py +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/static/assets/elk-worker.min-BdOC9sib.js +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/static/assets/svgToPng-CCU1Oj7k.js +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/static/logo.svg +0 -0
- {serpentine_parser-0.2.1 → serpentine_parser-0.3.0}/src/serpentine/watcher.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: serpentine-parser
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Environment :: Web Environment
|
|
@@ -22,8 +22,8 @@ Requires-Dist: starlette>=0.38.0
|
|
|
22
22
|
Requires-Dist: uvicorn[standard]>=0.30.0
|
|
23
23
|
Requires-Dist: websockets>=12.0
|
|
24
24
|
License-File: LICENSE
|
|
25
|
-
Summary: Fast dependency graph analysis and visualization for Python, JavaScript/TypeScript, and
|
|
26
|
-
Keywords: dependency-graph,visualization,static-analysis,python,javascript,rust,tree-sitter
|
|
25
|
+
Summary: Fast dependency graph analysis and visualization for Python, JavaScript/TypeScript, Rust, and Terraform projects
|
|
26
|
+
Keywords: dependency-graph,visualization,static-analysis,python,javascript,rust,terraform,tree-sitter
|
|
27
27
|
Author: Christopher Garretty
|
|
28
28
|
Requires-Python: >=3.10
|
|
29
29
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
@@ -41,13 +41,13 @@ See every reference between every named entity in your codebase — functions, c
|
|
|
41
41
|
|
|
42
42
|

|
|
43
43
|
|
|
44
|
-
Serpentine builds a **code reference graph** for Python, JavaScript/TypeScript, and
|
|
44
|
+
Serpentine builds a **code reference graph** for Python, JavaScript/TypeScript, Rust, and Terraform projects. A code reference is when one named entity mentions another by name — a function call, a type annotation, an assignment, an inheritance declaration. Serpentine resolves each reference through the language's scoping rules down to the exact definition it points to, then visualizes the result as an interactive graph that updates in real time as you edit.
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
48
|
## Features
|
|
49
49
|
|
|
50
|
-
- **Multi-language**: Python, JavaScript, TypeScript, and
|
|
50
|
+
- **Multi-language**: Python, JavaScript, TypeScript, Rust, and Terraform
|
|
51
51
|
- **Full reference resolution**: Traces calls, type annotations, assignments, and inheritance — not just import edges
|
|
52
52
|
- **Interactive graph**: Expandable nodes, search, pan/zoom, collapsible modules
|
|
53
53
|
- **Real-time updates**: File watcher pushes changes via WebSocket
|
|
@@ -104,7 +104,7 @@ This installs the `serpentine` CLI globally via `uv tool`, which you will need t
|
|
|
104
104
|
|
|
105
105
|
## Quick Start
|
|
106
106
|
|
|
107
|
-
Navigate to any Python, JavaScript/TypeScript, or
|
|
107
|
+
Navigate to any Python, JavaScript/TypeScript, Rust, or Terraform project and run:
|
|
108
108
|
|
|
109
109
|
```bash
|
|
110
110
|
serpentine serve
|
|
@@ -153,6 +153,7 @@ Options:
|
|
|
153
153
|
--include-standard Include stdlib nodes (default: off)
|
|
154
154
|
--include-third-party Include third-party nodes (default: off)
|
|
155
155
|
--state TEXT Filter by change state: modified,added,deleted
|
|
156
|
+
--edge-type TEXT Comma-separated edge types to include: calls,is-a,has-a,references,imports
|
|
156
157
|
```
|
|
157
158
|
|
|
158
159
|
### `serpentine catalog`
|
|
@@ -346,7 +347,7 @@ Serpentine looks for `.serpentine.yml` or `serpentine.yml` in the project root.
|
|
|
346
347
|
```yaml
|
|
347
348
|
analysis:
|
|
348
349
|
# File extensions to analyze (default: all supported)
|
|
349
|
-
extensions: [".py", ".js", ".jsx", ".ts", ".tsx", ".rs"]
|
|
350
|
+
extensions: [".py", ".js", ".jsx", ".ts", ".tsx", ".rs", ".tf"]
|
|
350
351
|
|
|
351
352
|
# Directories to skip
|
|
352
353
|
exclude_dirs:
|
|
@@ -427,6 +428,7 @@ serpentine/
|
|
|
427
428
|
│ ├── python/ # Python parser
|
|
428
429
|
│ ├── javascript/ # JS/TS parser
|
|
429
430
|
│ ├── rust_lang/ # Rust parser
|
|
431
|
+
│ ├── terraform/ # Terraform/HCL parser
|
|
430
432
|
│ ├── subscribers/ # Event processors (imports, calls, defs)
|
|
431
433
|
│ └── graph/ # Graph builder and resolvers
|
|
432
434
|
├── src/serpentine/ # Python package
|
|
@@ -8,13 +8,13 @@ See every reference between every named entity in your codebase — functions, c
|
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
Serpentine builds a **code reference graph** for Python, JavaScript/TypeScript, and
|
|
11
|
+
Serpentine builds a **code reference graph** for Python, JavaScript/TypeScript, Rust, and Terraform projects. A code reference is when one named entity mentions another by name — a function call, a type annotation, an assignment, an inheritance declaration. Serpentine resolves each reference through the language's scoping rules down to the exact definition it points to, then visualizes the result as an interactive graph that updates in real time as you edit.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
## Features
|
|
16
16
|
|
|
17
|
-
- **Multi-language**: Python, JavaScript, TypeScript, and
|
|
17
|
+
- **Multi-language**: Python, JavaScript, TypeScript, Rust, and Terraform
|
|
18
18
|
- **Full reference resolution**: Traces calls, type annotations, assignments, and inheritance — not just import edges
|
|
19
19
|
- **Interactive graph**: Expandable nodes, search, pan/zoom, collapsible modules
|
|
20
20
|
- **Real-time updates**: File watcher pushes changes via WebSocket
|
|
@@ -71,7 +71,7 @@ This installs the `serpentine` CLI globally via `uv tool`, which you will need t
|
|
|
71
71
|
|
|
72
72
|
## Quick Start
|
|
73
73
|
|
|
74
|
-
Navigate to any Python, JavaScript/TypeScript, or
|
|
74
|
+
Navigate to any Python, JavaScript/TypeScript, Rust, or Terraform project and run:
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
77
|
serpentine serve
|
|
@@ -120,6 +120,7 @@ Options:
|
|
|
120
120
|
--include-standard Include stdlib nodes (default: off)
|
|
121
121
|
--include-third-party Include third-party nodes (default: off)
|
|
122
122
|
--state TEXT Filter by change state: modified,added,deleted
|
|
123
|
+
--edge-type TEXT Comma-separated edge types to include: calls,is-a,has-a,references,imports
|
|
123
124
|
```
|
|
124
125
|
|
|
125
126
|
### `serpentine catalog`
|
|
@@ -313,7 +314,7 @@ Serpentine looks for `.serpentine.yml` or `serpentine.yml` in the project root.
|
|
|
313
314
|
```yaml
|
|
314
315
|
analysis:
|
|
315
316
|
# File extensions to analyze (default: all supported)
|
|
316
|
-
extensions: [".py", ".js", ".jsx", ".ts", ".tsx", ".rs"]
|
|
317
|
+
extensions: [".py", ".js", ".jsx", ".ts", ".tsx", ".rs", ".tf"]
|
|
317
318
|
|
|
318
319
|
# Directories to skip
|
|
319
320
|
exclude_dirs:
|
|
@@ -394,6 +395,7 @@ serpentine/
|
|
|
394
395
|
│ ├── python/ # Python parser
|
|
395
396
|
│ ├── javascript/ # JS/TS parser
|
|
396
397
|
│ ├── rust_lang/ # Rust parser
|
|
398
|
+
│ ├── terraform/ # Terraform/HCL parser
|
|
397
399
|
│ ├── subscribers/ # Event processors (imports, calls, defs)
|
|
398
400
|
│ └── graph/ # Graph builder and resolvers
|
|
399
401
|
├── src/serpentine/ # Python package
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "serpentine-parser"
|
|
3
|
-
version = "0.
|
|
4
|
-
description = "Fast dependency graph analysis and visualization for Python, JavaScript/TypeScript, and
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "Fast dependency graph analysis and visualization for Python, JavaScript/TypeScript, Rust, and Terraform projects"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
license = { file = "LICENSE" }
|
|
8
8
|
authors = [
|
|
9
9
|
{ name = "Christopher Garretty" },
|
|
10
10
|
]
|
|
11
|
-
keywords = ["dependency-graph", "visualization", "static-analysis", "python", "javascript", "rust", "tree-sitter"]
|
|
11
|
+
keywords = ["dependency-graph", "visualization", "static-analysis", "python", "javascript", "rust", "terraform", "tree-sitter"]
|
|
12
12
|
classifiers = [
|
|
13
13
|
"Development Status :: 4 - Beta",
|
|
14
14
|
"Environment :: Console",
|
|
@@ -13,9 +13,13 @@ dependencies = [
|
|
|
13
13
|
|
|
14
14
|
[[package]]
|
|
15
15
|
name = "cc"
|
|
16
|
-
version = "1.
|
|
16
|
+
version = "1.2.63"
|
|
17
17
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
|
-
checksum = "
|
|
18
|
+
checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f"
|
|
19
|
+
dependencies = [
|
|
20
|
+
"find-msvc-tools",
|
|
21
|
+
"shlex",
|
|
22
|
+
]
|
|
19
23
|
|
|
20
24
|
[[package]]
|
|
21
25
|
name = "crossbeam-deque"
|
|
@@ -44,9 +48,27 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
|
44
48
|
|
|
45
49
|
[[package]]
|
|
46
50
|
name = "either"
|
|
47
|
-
version = "1.
|
|
51
|
+
version = "1.16.0"
|
|
52
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
53
|
+
checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
|
|
54
|
+
|
|
55
|
+
[[package]]
|
|
56
|
+
name = "equivalent"
|
|
57
|
+
version = "1.0.2"
|
|
48
58
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
49
|
-
checksum = "
|
|
59
|
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
60
|
+
|
|
61
|
+
[[package]]
|
|
62
|
+
name = "find-msvc-tools"
|
|
63
|
+
version = "0.1.9"
|
|
64
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
65
|
+
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
|
66
|
+
|
|
67
|
+
[[package]]
|
|
68
|
+
name = "hashbrown"
|
|
69
|
+
version = "0.17.1"
|
|
70
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
71
|
+
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
|
50
72
|
|
|
51
73
|
[[package]]
|
|
52
74
|
name = "heck"
|
|
@@ -54,23 +76,33 @@ version = "0.5.0"
|
|
|
54
76
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
55
77
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
56
78
|
|
|
79
|
+
[[package]]
|
|
80
|
+
name = "indexmap"
|
|
81
|
+
version = "2.14.0"
|
|
82
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
83
|
+
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
|
84
|
+
dependencies = [
|
|
85
|
+
"equivalent",
|
|
86
|
+
"hashbrown",
|
|
87
|
+
]
|
|
88
|
+
|
|
57
89
|
[[package]]
|
|
58
90
|
name = "itoa"
|
|
59
|
-
version = "1.0.
|
|
91
|
+
version = "1.0.18"
|
|
60
92
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
61
|
-
checksum = "
|
|
93
|
+
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
62
94
|
|
|
63
95
|
[[package]]
|
|
64
96
|
name = "libc"
|
|
65
|
-
version = "0.2.
|
|
97
|
+
version = "0.2.186"
|
|
66
98
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
67
|
-
checksum = "
|
|
99
|
+
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|
68
100
|
|
|
69
101
|
[[package]]
|
|
70
102
|
name = "memchr"
|
|
71
|
-
version = "2.8.
|
|
103
|
+
version = "2.8.1"
|
|
72
104
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
73
|
-
checksum = "
|
|
105
|
+
checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
|
|
74
106
|
|
|
75
107
|
[[package]]
|
|
76
108
|
name = "once_cell"
|
|
@@ -162,9 +194,9 @@ dependencies = [
|
|
|
162
194
|
|
|
163
195
|
[[package]]
|
|
164
196
|
name = "rayon"
|
|
165
|
-
version = "1.
|
|
197
|
+
version = "1.12.0"
|
|
166
198
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
167
|
-
checksum = "
|
|
199
|
+
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
|
168
200
|
dependencies = [
|
|
169
201
|
"either",
|
|
170
202
|
"rayon-core",
|
|
@@ -241,10 +273,11 @@ dependencies = [
|
|
|
241
273
|
|
|
242
274
|
[[package]]
|
|
243
275
|
name = "serde_json"
|
|
244
|
-
version = "1.0.
|
|
276
|
+
version = "1.0.150"
|
|
245
277
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
246
|
-
checksum = "
|
|
278
|
+
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
|
|
247
279
|
dependencies = [
|
|
280
|
+
"indexmap",
|
|
248
281
|
"itoa",
|
|
249
282
|
"memchr",
|
|
250
283
|
"serde",
|
|
@@ -254,19 +287,32 @@ dependencies = [
|
|
|
254
287
|
|
|
255
288
|
[[package]]
|
|
256
289
|
name = "serpentine"
|
|
257
|
-
version = "0.
|
|
290
|
+
version = "0.3.0"
|
|
258
291
|
dependencies = [
|
|
259
292
|
"pyo3",
|
|
260
293
|
"rayon",
|
|
261
294
|
"serde",
|
|
262
295
|
"serde_json",
|
|
263
296
|
"tree-sitter",
|
|
297
|
+
"tree-sitter-hcl",
|
|
264
298
|
"tree-sitter-javascript",
|
|
265
299
|
"tree-sitter-python",
|
|
266
300
|
"tree-sitter-rust",
|
|
267
301
|
"tree-sitter-typescript",
|
|
268
302
|
]
|
|
269
303
|
|
|
304
|
+
[[package]]
|
|
305
|
+
name = "shlex"
|
|
306
|
+
version = "2.0.1"
|
|
307
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
308
|
+
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
|
309
|
+
|
|
310
|
+
[[package]]
|
|
311
|
+
name = "streaming-iterator"
|
|
312
|
+
version = "0.1.9"
|
|
313
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
314
|
+
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
|
|
315
|
+
|
|
270
316
|
[[package]]
|
|
271
317
|
name = "syn"
|
|
272
318
|
version = "2.0.117"
|
|
@@ -286,52 +332,72 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
|
286
332
|
|
|
287
333
|
[[package]]
|
|
288
334
|
name = "tree-sitter"
|
|
289
|
-
version = "0.
|
|
335
|
+
version = "0.25.10"
|
|
290
336
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
291
|
-
checksum = "
|
|
337
|
+
checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87"
|
|
292
338
|
dependencies = [
|
|
293
339
|
"cc",
|
|
294
340
|
"regex",
|
|
341
|
+
"regex-syntax",
|
|
342
|
+
"serde_json",
|
|
343
|
+
"streaming-iterator",
|
|
344
|
+
"tree-sitter-language",
|
|
345
|
+
]
|
|
346
|
+
|
|
347
|
+
[[package]]
|
|
348
|
+
name = "tree-sitter-hcl"
|
|
349
|
+
version = "1.1.0"
|
|
350
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
351
|
+
checksum = "5a7b2cc3d7121553b84309fab9d11b3ff3d420403eef9ae50f9fd1cd9d9cf012"
|
|
352
|
+
dependencies = [
|
|
353
|
+
"cc",
|
|
354
|
+
"tree-sitter-language",
|
|
295
355
|
]
|
|
296
356
|
|
|
297
357
|
[[package]]
|
|
298
358
|
name = "tree-sitter-javascript"
|
|
299
|
-
version = "0.
|
|
359
|
+
version = "0.25.0"
|
|
300
360
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
301
|
-
checksum = "
|
|
361
|
+
checksum = "68204f2abc0627a90bdf06e605f5c470aa26fdcb2081ea553a04bdad756693f5"
|
|
302
362
|
dependencies = [
|
|
303
363
|
"cc",
|
|
304
|
-
"tree-sitter",
|
|
364
|
+
"tree-sitter-language",
|
|
305
365
|
]
|
|
306
366
|
|
|
367
|
+
[[package]]
|
|
368
|
+
name = "tree-sitter-language"
|
|
369
|
+
version = "0.1.7"
|
|
370
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
371
|
+
checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782"
|
|
372
|
+
|
|
307
373
|
[[package]]
|
|
308
374
|
name = "tree-sitter-python"
|
|
309
|
-
version = "0.
|
|
375
|
+
version = "0.25.0"
|
|
310
376
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
311
|
-
checksum = "
|
|
377
|
+
checksum = "6bf85fd39652e740bf60f46f4cda9492c3a9ad75880575bf14960f775cb74a1c"
|
|
312
378
|
dependencies = [
|
|
313
379
|
"cc",
|
|
314
|
-
"tree-sitter",
|
|
380
|
+
"tree-sitter-language",
|
|
315
381
|
]
|
|
316
382
|
|
|
317
383
|
[[package]]
|
|
318
384
|
name = "tree-sitter-rust"
|
|
319
|
-
version = "0.
|
|
385
|
+
version = "0.24.2"
|
|
320
386
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
321
|
-
checksum = "
|
|
387
|
+
checksum = "439e577dbe07423ec2582ac62c7531120dbfccfa6e5f92406f93dd271a120e45"
|
|
322
388
|
dependencies = [
|
|
323
389
|
"cc",
|
|
324
|
-
"tree-sitter",
|
|
390
|
+
"tree-sitter-language",
|
|
325
391
|
]
|
|
326
392
|
|
|
327
393
|
[[package]]
|
|
328
394
|
name = "tree-sitter-typescript"
|
|
329
|
-
version = "0.
|
|
395
|
+
version = "0.23.2"
|
|
330
396
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
331
|
-
checksum = "
|
|
397
|
+
checksum = "6c5f76ed8d947a75cc446d5fccd8b602ebf0cde64ccf2ffa434d873d7a575eff"
|
|
332
398
|
dependencies = [
|
|
333
399
|
"cc",
|
|
334
|
-
"tree-sitter",
|
|
400
|
+
"tree-sitter-language",
|
|
335
401
|
]
|
|
336
402
|
|
|
337
403
|
[[package]]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "serpentine"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
|
|
@@ -9,11 +9,12 @@ name = "serpentine"
|
|
|
9
9
|
crate-type = ["cdylib", "rlib"]
|
|
10
10
|
|
|
11
11
|
[dependencies]
|
|
12
|
-
tree-sitter = "0.
|
|
13
|
-
tree-sitter-python = { version = "0.
|
|
14
|
-
tree-sitter-javascript = { version = "0.
|
|
15
|
-
tree-sitter-typescript = { version = "0.
|
|
16
|
-
tree-sitter-rust = { version = "0.
|
|
12
|
+
tree-sitter = "0.25"
|
|
13
|
+
tree-sitter-python = { version = "0.25", default-features = false }
|
|
14
|
+
tree-sitter-javascript = { version = "0.25", default-features = false }
|
|
15
|
+
tree-sitter-typescript = { version = "0.23", default-features = false }
|
|
16
|
+
tree-sitter-rust = { version = "0.24", default-features = false }
|
|
17
|
+
tree-sitter-hcl = "1.1.0"
|
|
17
18
|
pyo3 = { version = "0.28", features = ["extension-module", "abi3-py310"] }
|
|
18
19
|
rayon = "1.10"
|
|
19
20
|
serde = { version = "1.0", features = ["derive"] }
|
|
@@ -478,6 +478,18 @@ impl GraphBuilder {
|
|
|
478
478
|
|
|
479
479
|
let resolved_module = source_module.to_string();
|
|
480
480
|
|
|
481
|
+
// Only emit imports edges for project-local targets. Terraform (.tf) files
|
|
482
|
+
// are exempt: their source paths are already normalized from "./" prefixes
|
|
483
|
+
// by normalize_source_path, so all surviving sources are local-by-intent
|
|
484
|
+
// even when the target file is not in the analyzed set.
|
|
485
|
+
let is_terraform = file.ends_with(".tf");
|
|
486
|
+
if !is_terraform {
|
|
487
|
+
use crate::graph::Origin;
|
|
488
|
+
if self.classify_module(&resolved_module) != Origin::Local {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
481
493
|
// Determine what to create an edge to
|
|
482
494
|
if imported_names.is_empty() {
|
|
483
495
|
// `import foo` or `import foo.bar` - edge to the module itself
|
|
@@ -963,7 +975,12 @@ impl GraphBuilder {
|
|
|
963
975
|
// For method calls on local variables (`obj.method(arg)`), emit
|
|
964
976
|
// `obj --references--> arg` for each local-variable argument.
|
|
965
977
|
// This captures the data-flow dependency: obj "uses" its arguments.
|
|
966
|
-
|
|
978
|
+
// Guard: only fire when the receiver (`caller`) is a local variable in
|
|
979
|
+
// the current scope — i.e. its qualname starts with the scope prefix.
|
|
980
|
+
// Without this, `ClassName.static_method(arg)` from another module
|
|
981
|
+
// falsely emits `ClassName --references--> arg`.
|
|
982
|
+
let scope_prefix = format!("{}.", scope);
|
|
983
|
+
if caller != scope && callee_text.contains('.') && caller.starts_with(&scope_prefix) {
|
|
967
984
|
let call_args: Vec<String> = target_obj
|
|
968
985
|
.get("arguments")
|
|
969
986
|
.and_then(|a| a.as_array())
|
|
@@ -973,7 +990,6 @@ impl GraphBuilder {
|
|
|
973
990
|
.collect()
|
|
974
991
|
})
|
|
975
992
|
.unwrap_or_default();
|
|
976
|
-
let scope_prefix = format!("{}.", scope);
|
|
977
993
|
for arg_text in &call_args {
|
|
978
994
|
let idents: Vec<String> =
|
|
979
995
|
if arg_text.chars().all(|c| c.is_alphanumeric() || c == '_') {
|
|
@@ -14,6 +14,7 @@ mod message_bus;
|
|
|
14
14
|
mod python;
|
|
15
15
|
mod rust_lang;
|
|
16
16
|
mod subscribers;
|
|
17
|
+
mod terraform;
|
|
17
18
|
|
|
18
19
|
use crate::javascript::{parse as parse_javascript, JsLang};
|
|
19
20
|
use crate::javascript::config::JsConfig;
|
|
@@ -22,6 +23,8 @@ use crate::graph::GraphBuilder;
|
|
|
22
23
|
use crate::python::parse as parse_python;
|
|
23
24
|
use crate::python::config::PythonConfig;
|
|
24
25
|
use crate::rust_lang::parse as parse_rust;
|
|
26
|
+
use crate::terraform::parse as parse_terraform;
|
|
27
|
+
use crate::terraform::config::TerraformConfig;
|
|
25
28
|
use crate::subscribers::{
|
|
26
29
|
DecoratorsSubscriberFactory, PdgSubscriberFactory, CodeSnippetSubscriberFactory,
|
|
27
30
|
DefinitionsSubscriberFactory, EventCounterSubscriberFactory, ImportsSubscriberFactory,
|
|
@@ -39,10 +42,11 @@ use pyo3::types::{PyDict, PyList};
|
|
|
39
42
|
|
|
40
43
|
use tree_sitter::{Language, Parser, Tree};
|
|
41
44
|
|
|
42
|
-
use tree_sitter_javascript::
|
|
43
|
-
use tree_sitter_python::
|
|
44
|
-
use tree_sitter_rust::
|
|
45
|
-
use tree_sitter_typescript::{
|
|
45
|
+
use tree_sitter_javascript::LANGUAGE as JAVASCRIPT_LANGUAGE;
|
|
46
|
+
use tree_sitter_python::LANGUAGE as PYTHON_LANGUAGE;
|
|
47
|
+
use tree_sitter_rust::LANGUAGE as RUST_LANGUAGE;
|
|
48
|
+
use tree_sitter_typescript::{LANGUAGE_TSX, LANGUAGE_TYPESCRIPT};
|
|
49
|
+
|
|
46
50
|
|
|
47
51
|
// ============================================================================
|
|
48
52
|
// Language Support
|
|
@@ -60,6 +64,8 @@ enum Lang {
|
|
|
60
64
|
Tsx,
|
|
61
65
|
/// Rust (.rs)
|
|
62
66
|
Rust,
|
|
67
|
+
/// Terraform/HCL (.tf)
|
|
68
|
+
Terraform,
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
impl Lang {
|
|
@@ -71,6 +77,7 @@ impl Lang {
|
|
|
71
77
|
Some("ts") => Some(Lang::TypeScript),
|
|
72
78
|
Some("tsx") => Some(Lang::Tsx),
|
|
73
79
|
Some("rs") => Some(Lang::Rust),
|
|
80
|
+
Some("tf") => Some(Lang::Terraform),
|
|
74
81
|
_ => None,
|
|
75
82
|
}
|
|
76
83
|
}
|
|
@@ -78,11 +85,12 @@ impl Lang {
|
|
|
78
85
|
/// Get the tree-sitter language for parsing.
|
|
79
86
|
fn language(&self) -> Language {
|
|
80
87
|
match self {
|
|
81
|
-
Lang::Python =>
|
|
82
|
-
Lang::JavaScript =>
|
|
83
|
-
Lang::TypeScript =>
|
|
84
|
-
Lang::Tsx =>
|
|
85
|
-
Lang::Rust =>
|
|
88
|
+
Lang::Python => PYTHON_LANGUAGE.into(),
|
|
89
|
+
Lang::JavaScript => JAVASCRIPT_LANGUAGE.into(),
|
|
90
|
+
Lang::TypeScript => LANGUAGE_TYPESCRIPT.into(),
|
|
91
|
+
Lang::Tsx => LANGUAGE_TSX.into(),
|
|
92
|
+
Lang::Rust => RUST_LANGUAGE.into(),
|
|
93
|
+
Lang::Terraform => tree_sitter_hcl::LANGUAGE.into(),
|
|
86
94
|
}
|
|
87
95
|
}
|
|
88
96
|
|
|
@@ -92,7 +100,7 @@ impl Lang {
|
|
|
92
100
|
Lang::JavaScript => Some(JsLang::JavaScript),
|
|
93
101
|
Lang::TypeScript => Some(JsLang::TypeScript),
|
|
94
102
|
Lang::Tsx => Some(JsLang::Tsx),
|
|
95
|
-
Lang::Python | Lang::Rust => None,
|
|
103
|
+
Lang::Python | Lang::Rust | Lang::Terraform => None,
|
|
96
104
|
}
|
|
97
105
|
}
|
|
98
106
|
}
|
|
@@ -117,7 +125,7 @@ struct FileEntry {
|
|
|
117
125
|
impl FileEntry {
|
|
118
126
|
fn new(lang: Lang, source: String, file_path: String) -> Self {
|
|
119
127
|
let mut parser = Parser::new();
|
|
120
|
-
parser.set_language(lang.language()).unwrap();
|
|
128
|
+
parser.set_language(&lang.language()).unwrap();
|
|
121
129
|
let source_hash = Self::compute_hash(&source);
|
|
122
130
|
let tree = parser.parse(&source, None);
|
|
123
131
|
|
|
@@ -177,6 +185,7 @@ impl FileEntry {
|
|
|
177
185
|
parse_javascript(&self.source, &self.tree, &self.file_path, js_lang)
|
|
178
186
|
}
|
|
179
187
|
Lang::Rust => parse_rust(&self.source, &self.tree, &self.file_path),
|
|
188
|
+
Lang::Terraform => parse_terraform(&self.source, &self.tree, &self.file_path),
|
|
180
189
|
};
|
|
181
190
|
|
|
182
191
|
self.cached_results = self.message_bus.publish_events(events)?;
|
|
@@ -287,6 +296,7 @@ impl FileManager {
|
|
|
287
296
|
Box::new(PythonConfig::new()),
|
|
288
297
|
Box::new(JsConfig::new()),
|
|
289
298
|
Box::new(crate::rust_lang::config::RustConfig::new()),
|
|
299
|
+
Box::new(TerraformConfig::new()),
|
|
290
300
|
];
|
|
291
301
|
|
|
292
302
|
// Collect all subscriber data from all files (already cached from parsing)
|
|
@@ -323,6 +333,16 @@ impl FileManager {
|
|
|
323
333
|
for data in all_definitions {
|
|
324
334
|
builder.load_definitions(&data);
|
|
325
335
|
}
|
|
336
|
+
|
|
337
|
+
// Populate local_prefixes from the set of analyzed file paths so that
|
|
338
|
+
// classify_module can distinguish project-local modules from third-party.
|
|
339
|
+
for path in self.files.keys() {
|
|
340
|
+
let module_path = builder.file_to_module(&path.to_string_lossy());
|
|
341
|
+
let top = module_path.split('.').next().unwrap_or(&module_path).to_string();
|
|
342
|
+
if !top.is_empty() {
|
|
343
|
+
builder.local_prefixes.insert(top);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
326
346
|
for data in all_pdgs {
|
|
327
347
|
builder.load_pdgs(&data);
|
|
328
348
|
}
|