lang-parsing-substrate 0.5.1__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.
Files changed (35) hide show
  1. lang_parsing_substrate-0.5.1/.github/workflows/build.yml +103 -0
  2. lang_parsing_substrate-0.5.1/.github/workflows/wheels.yml +121 -0
  3. lang_parsing_substrate-0.5.1/.gitignore +6 -0
  4. lang_parsing_substrate-0.5.1/.pre-commit-config.yaml +55 -0
  5. lang_parsing_substrate-0.5.1/CLAUDE.md +67 -0
  6. lang_parsing_substrate-0.5.1/Cargo.lock +567 -0
  7. lang_parsing_substrate-0.5.1/Cargo.toml +69 -0
  8. lang_parsing_substrate-0.5.1/LICENSE +21 -0
  9. lang_parsing_substrate-0.5.1/PKG-INFO +221 -0
  10. lang_parsing_substrate-0.5.1/README.md +201 -0
  11. lang_parsing_substrate-0.5.1/about.hbs +19 -0
  12. lang_parsing_substrate-0.5.1/about.toml +24 -0
  13. lang_parsing_substrate-0.5.1/docs/migration-knots.md +141 -0
  14. lang_parsing_substrate-0.5.1/docs/migration-tools_sqc.md +137 -0
  15. lang_parsing_substrate-0.5.1/docs/releasing.md +91 -0
  16. lang_parsing_substrate-0.5.1/docs/research-c-standard-detection.md +335 -0
  17. lang_parsing_substrate-0.5.1/docs/unified-config-spec.md +248 -0
  18. lang_parsing_substrate-0.5.1/pyproject.toml +39 -0
  19. lang_parsing_substrate-0.5.1/rust-toolchain.toml +3 -0
  20. lang_parsing_substrate-0.5.1/src/c_standard.rs +302 -0
  21. lang_parsing_substrate-0.5.1/src/calls.rs +1299 -0
  22. lang_parsing_substrate-0.5.1/src/cfg.rs +786 -0
  23. lang_parsing_substrate-0.5.1/src/cpp_header.rs +188 -0
  24. lang_parsing_substrate-0.5.1/src/fingerprint.rs +388 -0
  25. lang_parsing_substrate-0.5.1/src/imports.rs +466 -0
  26. lang_parsing_substrate-0.5.1/src/lib.rs +73 -0
  27. lang_parsing_substrate-0.5.1/src/path_ignore.rs +71 -0
  28. lang_parsing_substrate-0.5.1/src/py.rs +356 -0
  29. lang_parsing_substrate-0.5.1/src/query.rs +249 -0
  30. lang_parsing_substrate-0.5.1/src/regions.rs +248 -0
  31. lang_parsing_substrate-0.5.1/src/registry.rs +617 -0
  32. lang_parsing_substrate-0.5.1/src/suppressions.rs +213 -0
  33. lang_parsing_substrate-0.5.1/tasks.py +184 -0
  34. lang_parsing_substrate-0.5.1/tests/python/test_bindings.py +79 -0
  35. lang_parsing_substrate-0.5.1/tests/smoke.rs +56 -0
@@ -0,0 +1,103 @@
1
+ name: Build and Test
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ tags:
8
+ - 'v*.*.*'
9
+ pull_request:
10
+ branches:
11
+ - main
12
+
13
+ jobs:
14
+ build:
15
+ name: Build and Test
16
+ runs-on: ubuntu-22.04
17
+
18
+ steps:
19
+ - name: Checkout code
20
+ uses: actions/checkout@v4
21
+
22
+ - name: Extract version from Cargo.toml
23
+ id: version
24
+ run: |
25
+ VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
26
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
27
+ echo "Extracted version: $VERSION"
28
+
29
+ - name: Install Rust toolchain
30
+ uses: dtolnay/rust-toolchain@stable
31
+ with:
32
+ components: clippy, rustfmt
33
+
34
+ - name: Verify Rust installation
35
+ run: |
36
+ rustc --version
37
+ cargo --version
38
+
39
+ - name: Cache cargo registry
40
+ uses: actions/cache@v4
41
+ with:
42
+ path: ~/.cargo/registry
43
+ key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
44
+
45
+ - name: Cache cargo index
46
+ uses: actions/cache@v4
47
+ with:
48
+ path: ~/.cargo/git
49
+ key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
50
+
51
+ - name: Cache target directory
52
+ uses: actions/cache@v4
53
+ with:
54
+ path: target
55
+ key: ${{ runner.os }}-target-${{ hashFiles('**/Cargo.lock') }}
56
+
57
+ - name: Security Audit
58
+ run: |
59
+ cargo install cargo-audit
60
+ cargo audit
61
+ continue-on-error: true
62
+
63
+ - name: Clippy (all features)
64
+ run: cargo clippy --all-features -- -D warnings
65
+
66
+ - name: Format check
67
+ run: cargo fmt --check
68
+
69
+ - name: Build (all features)
70
+ run: cargo build --all-features
71
+
72
+ - name: Build (subset — C/C++ only)
73
+ run: cargo build --no-default-features --features lang-c,lang-cpp
74
+
75
+ - name: Build (no features)
76
+ run: cargo build --no-default-features
77
+
78
+ - name: Test (all features)
79
+ run: cargo test --all-features
80
+
81
+ - name: Test (subset — C/C++ only)
82
+ run: cargo test --no-default-features --features lang-c,lang-cpp
83
+
84
+ - name: Install cargo-about
85
+ run: cargo install cargo-about --features cli
86
+
87
+ - name: Generate Third-Party Licenses
88
+ run: cargo about generate about.hbs -o THIRD_PARTY_LICENSES.txt
89
+
90
+ - name: Install cargo-cyclonedx
91
+ run: cargo install cargo-cyclonedx
92
+
93
+ - name: Generate SBOM (CycloneDX)
94
+ run: cargo cyclonedx --format json --spec-version 1.5
95
+
96
+ - name: Upload artifacts
97
+ uses: actions/upload-artifact@v4
98
+ with:
99
+ name: lang-parsing-substrate-${{ steps.version.outputs.VERSION }}
100
+ path: |
101
+ THIRD_PARTY_LICENSES.txt
102
+ lang-parsing-substrate.cdx.json
103
+ retention-days: 30
@@ -0,0 +1,121 @@
1
+ name: Wheels (PyPI)
2
+
3
+ # Build per-platform abi3 wheels + an sdist for the `lang-parsing-substrate`
4
+ # pyo3 bindings with maturin, and publish them to PyPI via Trusted Publishing
5
+ # (OIDC, no API token) on a v*.*.* tag.
6
+ #
7
+ # abi3-py310 (see Cargo.toml's pyo3 dependency) means ONE wheel per platform
8
+ # covers every CPython 3.10+, not one per minor version — no Python-version
9
+ # axis needed in the build matrix, unlike a non-abi3 pyo3 crate would need.
10
+ #
11
+ # Validate the matrix without publishing by running this workflow manually
12
+ # (Actions tab -> "Wheels (PyPI)" -> Run workflow); publish only happens on tags.
13
+
14
+ on:
15
+ push:
16
+ tags:
17
+ - 'v*.*.*'
18
+ workflow_dispatch:
19
+
20
+ permissions:
21
+ contents: read
22
+
23
+ jobs:
24
+ build:
25
+ name: build (${{ matrix.platform.id }})
26
+ runs-on: ${{ matrix.platform.runner }}
27
+ env:
28
+ # Passed into the manylinux/musl Docker containers via `--env CFLAGS`
29
+ # below — same fix build.yml already carries for its own native
30
+ # cargo-test builds. _BSD_SOURCE enables le16toh/be16toh on glibc 2.17
31
+ # (manylinux2014 predates _DEFAULT_SOURCE). -std=c11 is what
32
+ # tree-sitter-fortran's parser.c actually needs: manylinux's aarch64
33
+ # cross-compiler defaults to C89 and rejects its C99 `for`-loop
34
+ # declarations — confirmed live (aarch64 build failure, x86_64 fine) on
35
+ # the first run of this workflow before this was added.
36
+ CFLAGS: -D_BSD_SOURCE -std=c11
37
+ strategy:
38
+ fail-fast: false
39
+ matrix:
40
+ platform:
41
+ # `id` must be unique per row — macOS and Linux share the bare
42
+ # x86_64/aarch64 target labels, which would otherwise collide as
43
+ # artifact names (upload-artifact@v4 rejects duplicate names).
44
+ - { id: linux-x86_64, runner: ubuntu-22.04, target: x86_64, manylinux: auto }
45
+ - { id: linux-aarch64, runner: ubuntu-22.04, target: aarch64, manylinux: auto }
46
+ - { id: musl-x86_64, runner: ubuntu-22.04, target: x86_64-unknown-linux-musl, manylinux: musllinux_1_2 }
47
+ - { id: musl-aarch64, runner: ubuntu-22.04, target: aarch64-unknown-linux-musl, manylinux: musllinux_1_2 }
48
+ # Both macOS arches build on the Apple-Silicon runner; x86_64 is
49
+ # cross-compiled. Avoids the deprecated/scarce macos-13 Intel runners.
50
+ - { id: macos-x86_64, runner: macos-14, target: x86_64-apple-darwin }
51
+ - { id: macos-aarch64, runner: macos-14, target: aarch64 }
52
+ - { id: windows-x64, runner: windows-2022, target: x64 }
53
+ steps:
54
+ - uses: actions/checkout@v4
55
+
56
+ - name: Build wheel
57
+ uses: PyO3/maturin-action@v1
58
+ with:
59
+ command: build
60
+ target: ${{ matrix.platform.target }}
61
+ # No --features flag needed: pyproject.toml's [tool.maturin] already
62
+ # declares features = ["pyo3"], matching knots' own wheels.yml
63
+ # convention of letting pyproject.toml be the single source of the
64
+ # build's feature set.
65
+ args: --release --out dist
66
+ manylinux: ${{ matrix.platform.manylinux }}
67
+ sccache: 'true'
68
+ # Inherit CFLAGS from the job-level env (see above). Passing by name
69
+ # (no =value) lets docker copy it from the runner's environment,
70
+ # avoiding shell-quoting issues with multi-word values. Only
71
+ # containerized (linux) builds use docker-options; macOS/Windows
72
+ # ignore it, but the env var is harmless there too.
73
+ docker-options: --env CFLAGS
74
+
75
+ - name: Upload wheel artifact
76
+ uses: actions/upload-artifact@v4
77
+ with:
78
+ name: wheel-${{ matrix.platform.id }}
79
+ path: dist/*.whl
80
+
81
+ sdist:
82
+ name: sdist
83
+ runs-on: ubuntu-22.04
84
+ steps:
85
+ - uses: actions/checkout@v4
86
+
87
+ - name: Build sdist
88
+ uses: PyO3/maturin-action@v1
89
+ with:
90
+ command: sdist
91
+ args: --out dist
92
+
93
+ - name: Upload sdist artifact
94
+ uses: actions/upload-artifact@v4
95
+ with:
96
+ name: sdist
97
+ path: dist/*.tar.gz
98
+
99
+ publish:
100
+ name: Publish to PyPI
101
+ needs: [build, sdist]
102
+ runs-on: ubuntu-22.04
103
+ if: startsWith(github.ref, 'refs/tags/v')
104
+ environment: release
105
+ permissions:
106
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
107
+ steps:
108
+ - name: Download all artifacts
109
+ uses: actions/download-artifact@v4
110
+ with:
111
+ path: dist
112
+ merge-multiple: true # flatten wheel-*/ and sdist/ into dist/
113
+
114
+ - name: Publish to PyPI
115
+ uses: pypa/gh-action-pypi-publish@release/v1
116
+ with:
117
+ packages-dir: dist
118
+ # Idempotent re-runs: a version that partially published (e.g. one
119
+ # platform's wheel failed) skips the files already on PyPI on retry
120
+ # instead of erroring on "file already exists".
121
+ skip-existing: true
@@ -0,0 +1,6 @@
1
+ /target
2
+ Cargo.lock
3
+ todo.db
4
+ .todo-sqlite-cli
5
+ __pycache__/
6
+ *.pyc
@@ -0,0 +1,55 @@
1
+ # Pre-commit hooks for lang-parsing-substrate
2
+ # Install: pre-commit install
3
+ # Run manually: pre-commit run --all-files
4
+
5
+ repos:
6
+ - repo: https://github.com/pre-commit/pre-commit-hooks
7
+ rev: v4.6.0
8
+ hooks:
9
+ - id: trailing-whitespace
10
+ - id: end-of-file-fixer
11
+ - id: check-yaml
12
+ - id: check-toml
13
+ - id: check-added-large-files
14
+ - id: mixed-line-ending
15
+ args: [--fix=lf]
16
+
17
+ - repo: local
18
+ hooks:
19
+ - id: cargo-fmt
20
+ name: cargo fmt (auto-fix)
21
+ description: Format Rust code with rustfmt
22
+ entry: bash -c 'cargo fmt --all 2>&1 && echo "Formatting complete"'
23
+ language: system
24
+ pass_filenames: false
25
+ types: [rust]
26
+ verbose: true
27
+
28
+ - id: cargo-clippy
29
+ name: cargo clippy (all features)
30
+ description: Lint Rust code with Clippy - deny warnings (all targets, all 16 language features)
31
+ entry: bash -c 'cargo clippy --all-targets --all-features -- -D warnings 2>&1'
32
+ language: system
33
+ pass_filenames: false
34
+ types: [rust]
35
+ verbose: true
36
+
37
+ - id: cargo-test
38
+ name: cargo test (all features + lang-c,lang-cpp subset)
39
+ description: Run the test suite under the full feature set and the minimal C/C++ subset, matching CI
40
+ entry: bash -c 'cargo test --all-features 2>&1 && cargo test --no-default-features --features lang-c,lang-cpp 2>&1'
41
+ language: system
42
+ pass_filenames: false
43
+ types: [rust]
44
+ verbose: true
45
+
46
+ # knots complexity gate — prebuilt-wheel edition (language: python, pulls
47
+ # the `knots` wheel from PyPI instead of building from source). The default
48
+ # `knots` hook ships args [--aird-threshold=85], so no override is needed
49
+ # here. To tighten or add metrics, set `args:` (pre-commit replaces them
50
+ # wholesale), e.g. args: [--aird-threshold=85, --cognitive-threshold=20]
51
+ - repo: https://github.com/brandon-arrendondo/knots-pre-commit
52
+ rev: v1.13.1
53
+ hooks:
54
+ - id: knots
55
+ types: [rust]
@@ -0,0 +1,67 @@
1
+ # lang-parsing-substrate — developer guide for Claude
2
+
3
+ Shared Rust **library crate** — the common parsing substrate for knots, moldy, and tools_sqc.
4
+ Provides language detection, tree-sitter grammar dispatch, and `LanguageInfo` registry across
5
+ 16 languages, compiled in at build time via Cargo feature flags.
6
+
7
+ ## Repository layout
8
+
9
+ | Path | Purpose |
10
+ |------|---------|
11
+ | `src/lib.rs` | Crate root — module wiring, cfg-gated grammar re-exports (`pub use tree_sitter_*`) |
12
+ | `src/registry.rs` | `LanguageInfo`, `SlocMode`, `languages()`, `language_for_file()`, `language_for_header_content()`, `language_info_for_file()`, `sloc_mode_for_file()`, `is_source_extension`, `is_parseable_extension`, `supported_languages_report()` |
13
+ | `src/cpp_header.rs` | `looks_like_cpp()` — best-effort content sniff for `.h` (C vs C++), gated on `lang-c` + `lang-cpp` |
14
+ | `Cargo.toml` | 16 optional `lang-*` features + `all-languages` + `default = ["all-languages"]` |
15
+ | `tasks.py` | `invoke build / test / check / bump-version / publish / clean` |
16
+ | `todo.db` | Task tracking — run `todo-sqlite-cli list` to see open work |
17
+
18
+ ## Key invariants
19
+
20
+ - **`language_for_file` returns `Option<Language>`** — never a fallback. If a language feature is disabled, its extensions return `None`. It is extension-only (no I/O): `.h` always resolves to the C grammar regardless of content. Callers that already have the file's bytes and want best-effort C-vs-C++ disambiguation for `.h` should use `language_for_header_content(path, source)` instead (see `src/cpp_header.rs`) — it defers to `language_for_file` for every other extension and only overrides `.h` when the content contains an unambiguous C++-only construct.
21
+ - **`languages()` is runtime-constructed** via `OnceLock<Vec<LanguageInfo>>`. It cannot be a `const` because its contents vary by compiled feature set. Do not attempt to make it `const`.
22
+ - **Feature flags are the language gate** — every language is an optional Cargo dep. The `all-languages` feature enables all 16. Consumers use `default-features = false` to opt into a subset (e.g. tools_sqc only needs `lang-c,lang-cpp`).
23
+ - **Grammar re-exports are cfg-gated** — `pub use tree_sitter_rust` is `#[cfg(feature = "lang-rust")]`. Consumers reach grammars transitively without their own direct deps.
24
+
25
+ ## Adding a new language
26
+
27
+ 1. **`Cargo.toml`** — add `tree-sitter-<lang> = { version = "...", optional = true }` and a `lang-<name>` feature under `[features]`. Add it to `all-languages`.
28
+ 2. **`src/registry.rs` — `languages()`** — add a `#[cfg(feature = "lang-<name>")] v.push(LanguageInfo { ... })` block.
29
+ 3. **`src/registry.rs` — `language_for_file()`** — add a `#[cfg(feature = "lang-<name>")] Some("ext" | ...) => Some(...LANGUAGE.into())` arm. Keep C last (it matches `.h` which could shadow other languages if placed first).
30
+ 4. **`src/lib.rs`** — add `#[cfg(feature = "lang-<name>")] pub use tree_sitter_<name>;`
31
+
32
+ ## Three-tier consumer model
33
+
34
+ | Tool | Execution model | Cross-file features | Storage need |
35
+ |------|----------------|--------------------|----|
36
+ | knots | pre-commit or `--recursive` | OFF in single-file; ON in recursive | in-memory |
37
+ | moldy | pre-commit or `--recursive` | OFF in single-file; ON in recursive | in-memory |
38
+ | tools_sqc | always full-scan | always ON | SQLite (path+mtime keyed) |
39
+
40
+ Cross-file features (Tier 2: import graph, call graph; Tier 3: CFG; Tier 4: pattern matching)
41
+ are not yet implemented — see `todo.db` for open tasks.
42
+
43
+ ## Substrate capability tiers
44
+
45
+ | Tier | Content | Status |
46
+ |------|---------|--------|
47
+ | 1 | Parse layer — language detection, tree-sitter dispatch, source bytes | **Done** |
48
+ | 2 | Graph layer — import graph (Ce/Ca/Instability), call graph | Pending |
49
+ | 3 | Control flow / basic blocks | Pending |
50
+ | 4 | Pattern matching — generalized rule engine (from tools_sqc) | Pending |
51
+ | 5 | Fingerprinting / similarity (code dedup) | Speculative |
52
+
53
+ ## Related projects
54
+
55
+ - `../knots/` — complexity metrics tool; CLAUDE.md there is the knots developer guide
56
+ - `../moldy/` — formatting tool
57
+ - `../tools_sqc/` — CERT-C compliance tool; has the rule engine that becomes Tier 4
58
+
59
+ ## Fixed-form Fortran dependency note
60
+
61
+ Fixed-form Fortran (`.f`/`.for`/`.f77`) support was **dropped from `lang-fortran`** ahead of the
62
+ v0.1.0 crates.io release — `cargo publish` rejects any manifest containing a `git` dependency,
63
+ even on a fully optional feature, and `tree-sitter-fixed-form-fortran` only exists as a git dep on
64
+ the `brandon-arrendondo/tree-sitter-fixed-form-fortran` fork. `lang-fortran` now covers only
65
+ free-form Fortran (`tree-sitter-fortran`, a real crates.io dep). Re-add fixed-form once
66
+ `stadelmanma/tree-sitter-fixed-form-fortran` merges PR #4 (real crates.io version) or the fork is
67
+ itself published to crates.io.