From cefa0c73ff55e622c5fcf77c1299ed447abbe9f6 Mon Sep 17 00:00:00 2001 From: Luke Zehrung Date: Sat, 20 Jun 2026 12:14:11 -0400 Subject: [PATCH 1/3] Remove JS fallback shim package --- .github/workflows/release.yml | 7 +- PUBLISHING.md | 23 ++-- README.md | 6 +- codegraph-skill/codegraph/SKILL.md | 3 - docs/installation.md | 2 - ...26-05-12-graph-first-language-expansion.md | 14 ++- ...-06-performance-and-cache-opportunities.md | 6 +- docs/scenario-catalog.md | 6 +- package-lock.json | 51 ++++----- .../codegraph-js-fallback/js-fallback.cjs | 28 ----- .../codegraph-js-fallback/js-fallback.d.ts | 64 ----------- packages/codegraph-js-fallback/package.json | 26 ----- scripts/patch-tree-sitter-node24-lib.mjs | 87 --------------- scripts/patch-tree-sitter-node24.mjs | 23 ---- scripts/release-lib.mjs | 25 ----- scripts/release.mjs | 22 +--- src/graph-edge-collector.ts | 4 +- src/indexer.ts | 12 +-- src/indexer/build-index.ts | 12 +-- src/indexer/imports.ts | 6 +- .../{jsFallback.ts => jsTextImports.ts} | 0 src/indexer/imports/nativeCaptures.ts | 6 +- src/indexer/locals-and-exports.ts | 4 +- src/indexer/navigation-local.ts | 4 +- src/indexer/navigation-provenance.ts | 2 +- src/indexer/navigation-references.ts | 4 +- src/indexer/parse-context.ts | 8 +- src/indexer/scope.ts | 4 +- src/indexer/types.ts | 2 +- src/jsFallback.ts | 101 ------------------ src/languages.ts | 6 +- src/languages/definitions/loadLanguage.ts | 2 +- src/languages/filePrep.ts | 4 +- src/languages/types.ts | 10 +- src/parserBackend.ts | 101 ++++++++++++++++++ tests/detailed-symbol-native-only.test.ts | 90 ++++++++-------- tests/esm-language-loading.test.ts | 12 +-- tests/helpers/native.ts | 10 +- tests/js-fallback-loader.test.ts | 12 --- tests/languages/sql.test.ts | 14 +-- tests/native-parse-tree.test.ts | 8 +- tests/native-parser-ownership.test.ts | 36 +++---- tests/native-query-scope.test.ts | 14 +-- tests/native-runtime-mode.test.ts | 6 +- tests/native-tree-sitter.test.ts | 8 +- tests/package-metadata.test.ts | 49 +++------ tests/parser-backend-unavailable.test.ts | 12 +++ tests/patch-tree-sitter-node24.test.ts | 86 --------------- tests/release-script.test.ts | 53 +++------ 49 files changed, 340 insertions(+), 755 deletions(-) delete mode 100644 packages/codegraph-js-fallback/js-fallback.cjs delete mode 100644 packages/codegraph-js-fallback/js-fallback.d.ts delete mode 100644 packages/codegraph-js-fallback/package.json delete mode 100644 scripts/patch-tree-sitter-node24-lib.mjs delete mode 100644 scripts/patch-tree-sitter-node24.mjs rename src/indexer/imports/{jsFallback.ts => jsTextImports.ts} (100%) delete mode 100644 src/jsFallback.ts create mode 100644 src/parserBackend.ts delete mode 100644 tests/js-fallback-loader.test.ts create mode 100644 tests/parser-backend-unavailable.test.ts delete mode 100644 tests/patch-tree-sitter-node24.test.ts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 887bebee..a5f31d8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: inputs: release_type: - description: Release type for the root, native, and compatibility packages + description: Release type for the root and native packages required: true type: choice default: patch @@ -213,7 +213,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.PACKAGE_PUBLISH_TOKEN || secrets.GITHUB_TOKEN }} - run: npm run publish:${{ inputs.release_type }} -- --package root --package native --package js-fallback + run: npm run publish:${{ inputs.release_type }} -- --package root --package native - name: Create or update GitHub Release env: @@ -225,8 +225,6 @@ jobs: root_package_tag="@lzehrung/codegraph@$root_version" native_version="${{ needs.plan-release.outputs.native_version }}" native_tag="@lzehrung/codegraph-native@$native_version" - fallback_version=$(node -p "JSON.parse(require('node:fs').readFileSync('packages/codegraph-js-fallback/package.json', 'utf8')).version") - fallback_tag="@lzehrung/codegraph-js-fallback@$fallback_version" tarball=$(npm pack --ignore-scripts --json | jq -r '.[0].filename') release_notes=$(mktemp) { @@ -234,7 +232,6 @@ jobs: echo "" echo "- \`$root_package_tag\`" echo "- \`$native_tag\`" - echo "- \`$fallback_tag\`" } > "$release_notes" if gh release view "$root_tag" >/dev/null 2>&1; then gh release edit "$root_tag" --title "$root_tag" --notes-file "$release_notes" diff --git a/PUBLISHING.md b/PUBLISHING.md index 2d56773f..4d5dc908 100644 --- a/PUBLISHING.md +++ b/PUBLISHING.md @@ -1,12 +1,11 @@ # Publishing Guide -Codegraph publishes as three standalone packages: +Codegraph publishes as two standalone packages: - `@lzehrung/codegraph`: the main JS package and CLI - `@lzehrung/codegraph-native`: the optional native Tree-sitter meta package plus per-platform binary packages -- `@lzehrung/codegraph-js-fallback`: a compatibility shim package with no grammar bundle -The main package depends on the native package optionally, so installs still succeed when no matching native binary exists. The compatibility shim remains standalone and versioned separately for package continuity. +The main package depends on the native package optionally, so installs still succeed when no matching native binary exists. When native is unavailable, Codegraph degrades to reduced graph-only and regex recovery mode; there is no separate JavaScript parser fallback package. ## Fast Path @@ -29,7 +28,6 @@ npm run publish:resume `publish:*` does the same work and also publishes: - staged native target packages plus the `@lzehrung/codegraph-native` meta package when `@lzehrung/codegraph-native` is selected -- the `@lzehrung/codegraph-js-fallback` shim package when it changed - the root `@lzehrung/codegraph` package when it changed When a publish includes `@lzehrung/codegraph-native`, the script verifies the complete supported native target set before running the full test suite. A local WSL/macOS/Windows shell can only build its own target, so use the `release` GitHub Actions workflow or manually collect every target artifact before running a native publish locally. @@ -37,7 +35,7 @@ When a publish includes `@lzehrung/codegraph-native`, the script verifies the co You can force a package-scoped release with `--package`: ```powershell -npm run publish:patch -- --package js-fallback +npm run publish:patch -- --package root npm run release:minor -- --package @lzehrung/codegraph-native ``` @@ -47,8 +45,8 @@ Use the `release` GitHub Actions workflow when you want GitHub to cut a complete - Trigger it manually with `release_type=patch|minor|major`. - The workflow builds every target declared in `packages/codegraph-native/package.json` `napi.targets`. -- It collects the per-target npm package artifacts, then runs `npm run publish: -- --package root --package native --package js-fallback`. -- The publish step verifies that every supported native target artifact is present before publishing target packages, the native meta package, the compatibility js-fallback shim package, and the root package. +- It collects the per-target npm package artifacts, then runs `npm run publish: -- --package root --package native`. +- The publish step verifies that every supported native target artifact is present before publishing target packages, the native meta package, and the root package. - On success it pushes all package tags, creates or updates the overall `vX.Y.Z` GitHub Release for the root package version, and uploads the root `.tgz` asset. - The workflow refuses reruns from a commit that is already tagged for the current root version. A fresh Actions runner cannot reconstruct the dirty local resume state that `publish:resume` expects. - By default the workflow uses `GITHUB_TOKEN` for GitHub Packages. If an existing package is not linked to this repository or does not grant this repository write access, create a `PACKAGE_PUBLISH_TOKEN` Actions secret from a classic PAT that can write the `@lzehrung` packages; the workflow will use it for npm publishing. @@ -62,9 +60,6 @@ Use the `release` GitHub Actions workflow when you want GitHub to cut a complete - `@lzehrung/codegraph-native` - Publishes the meta package. - Resolves and loads the correct per-platform binary package. -- `@lzehrung/codegraph-js-fallback` - - Publishes the compatibility shim package. - - Does not ship grammar dependencies or depend on the root package through a local `file:` dependency. ## Manual Native Staging @@ -124,14 +119,10 @@ npm run publish:native:meta npm publish ``` -9. Publish the fallback package when it changed: - -```powershell -npm publish --workspace=@lzehrung/codegraph-js-fallback -``` +The root package should be published last so its optional native dependency points at the final native meta version. ## Release Notes -- `@lzehrung/codegraph`, `@lzehrung/codegraph-native`, and `@lzehrung/codegraph-js-fallback` version independently. +- `@lzehrung/codegraph` and `@lzehrung/codegraph-native` version independently. - `src/native/treeSitterNative.ts` prefers the installed `@lzehrung/codegraph-native` package and falls back to the local workspace package for development. - If a native binary or query is unavailable at runtime, Codegraph degrades to reduced graph-only and regex recovery mode. diff --git a/README.md b/README.md index b70ec6b1..dae51668 100644 --- a/README.md +++ b/README.md @@ -297,7 +297,7 @@ npm i -g @lzehrung/codegraph npm i -g https://github.com/lzehrung/codegraph/releases/download/vVERSION/lzehrung-codegraph-VERSION.tgz ``` -Replace `VERSION` with the release you want. The root tarball does not bundle the native addon; source-language parsing still needs the scoped native package path via the `@lzehrung` GitHub Packages registry. Without it, Codegraph runs in reduced graph-only mode. The `@lzehrung/codegraph-js-fallback` package is a compatibility shim, not an alternate parser bundle. +Replace `VERSION` with the release you want. The root tarball does not bundle the native addon; source-language parsing still needs the scoped native package path via the `@lzehrung` GitHub Packages registry. Without it, Codegraph runs in reduced graph-only and regex recovery mode. ## FAQ @@ -347,8 +347,8 @@ npm run publish:major npm run publish:resume ``` -Use `--package root`, `--package native`, or `--package js-fallback`, or a full package name when you need to force a specific package. +Use `--package root`, `--package native`, or a full package name when you need to force a specific package. -For GitHub-driven releases, use the manual `release` Actions workflow with `patch`, `minor`, or `major`. It publishes the root, native, and compatibility js-fallback shim packages together, pushes their tags, then creates or updates the overall `vX.Y.Z` GitHub Release with the packed root tarball asset. The workflow refuses reruns on an already-tagged release commit because fresh Actions runners cannot reconstruct the local `publish:resume` state. +For GitHub-driven releases, use the manual `release` Actions workflow with `patch`, `minor`, or `major`. It publishes the root and native packages together, pushes their tags, then creates or updates the overall `vX.Y.Z` GitHub Release with the packed root tarball asset. The workflow refuses reruns on an already-tagged release commit because fresh Actions runners cannot reconstruct the local `publish:resume` state. For the detailed release flow, native artifact staging, and tag behavior, see [PUBLISHING.md](./PUBLISHING.md). diff --git a/codegraph-skill/codegraph/SKILL.md b/codegraph-skill/codegraph/SKILL.md index 92452feb..54853d7c 100644 --- a/codegraph-skill/codegraph/SKILL.md +++ b/codegraph-skill/codegraph/SKILL.md @@ -80,9 +80,6 @@ Use the scoped packages only: - package: `@lzehrung/codegraph` - native backend: `@lzehrung/codegraph-native` -- compatibility shim: `@lzehrung/codegraph-js-fallback` - -The compatibility shim is not a grammar fallback. Do not suggest installing it to restore source-language parsing when the native backend is unavailable. Registry: diff --git a/docs/installation.md b/docs/installation.md index f06da472..4a3caf36 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -8,7 +8,6 @@ Requirements and install paths for local source checkouts, published packages, r - Published installs do not require Rust or a manual native setup step on supported targets. - Local source checkouts do not require Rust just to build `dist/`, but the native workspace addon only builds when Cargo is available. - If no compatible native artifact is available, Codegraph drops to reduced graph-only and regex recovery mode instead of loading JS grammars. -- The root package does not install a JavaScript grammar fallback. `@lzehrung/codegraph-js-fallback` is only a compatibility shim package and does not provide parser recovery unless a future release documents that capability explicitly. ## Option 1: Local source checkout @@ -84,7 +83,6 @@ Explicit CLI, library, and tool `native` options take precedence over `CODEGRAPH - `@lzehrung/codegraph`: main library and CLI - `@lzehrung/codegraph-native`: optional native runtime package that resolves the matching binary artifact -- `@lzehrung/codegraph-js-fallback`: compatibility shim package with no grammar bundle; installing it separately does not restore non-native Tree-sitter parsing Reduced mode preserves graph-only and regex-backed recovery where available; it does not provide a non-native Tree-sitter parser. diff --git a/docs/plans/2026-05-12-graph-first-language-expansion.md b/docs/plans/2026-05-12-graph-first-language-expansion.md index f1eaabdb..a28a1b32 100644 --- a/docs/plans/2026-05-12-graph-first-language-expansion.md +++ b/docs/plans/2026-05-12-graph-first-language-expansion.md @@ -5,7 +5,7 @@ ## Context -The repo has an established language-support workflow: define support surface, add a language definition, wire JS fallback and native grammars, add fixtures/tests, then update parity/scenario docs and the agent skill surface. Follow [docs/adding-language-support.md](../../adding-language-support.md) exactly. +The repo has an established language-support workflow: define support surface, add a language definition, wire native grammars and reduced-mode behavior, add fixtures/tests, then update parity/scenario docs and the agent skill surface. Follow [docs/adding-language-support.md](../../adding-language-support.md) exactly. This plan intentionally targets graph-first support. Each language should provide parsing, chunking, top-level symbol extraction, and static dependency edges. It should not claim full cross-file semantic navigation until shared `goto`, `references`, and native semantic parity tests prove that behavior. @@ -41,8 +41,8 @@ The product boundary is important: graph-first languages may participate in depe For each language, v1 support should provide: - File discovery for listed extensions. -- Tree-sitter parsing through JS fallback. -- Native parser support when the Rust grammar exposes a compatible API. +- Tree-sitter parsing through the native runtime when the Rust grammar exposes a compatible API. +- Reduced-mode graph and regex recovery that stays safe when native is unavailable. - Chunking for top-level declarations and important nested declarations. - Definition extraction for top-level names. - Static import/include/dependency extraction. @@ -76,7 +76,6 @@ Register them in: - `src/languages/all.ts` - `src/languages.ts` - `src/util/projectFiles.ts` if discovery is not fully driven by definitions -- `packages/codegraph-js-fallback/package.json` - `packages/codegraph-native/Cargo.toml` - `packages/codegraph-native/src/languages.rs` @@ -255,7 +254,6 @@ git commit -m "docs: define graph-first language tier" Files: -- `packages/codegraph-js-fallback/package.json` - `packages/codegraph-native/Cargo.toml` - `packages/codegraph-native/src/languages.rs` - `tests/native-tree-sitter.test.ts` @@ -263,8 +261,8 @@ Files: Changes: -- Add JS grammar dependencies for all seven languages. - Add Rust grammar dependencies for all seven languages. +- Keep reduced-mode behavior safe without adding a JavaScript grammar fallback. - Register native IDs using stable lowercase language ids: - `scala` - `lua` @@ -287,7 +285,7 @@ npx vitest run tests/native-tree-sitter.test.ts tests/native-parser-ownership.te Commit: ```bash -git add packages/codegraph-js-fallback/package.json packages/codegraph-native/Cargo.toml packages/codegraph-native/src/languages.rs package-lock.json tests/native-tree-sitter.test.ts tests/native-parser-ownership.test.ts +git add packages/codegraph-native/Cargo.toml packages/codegraph-native/src/languages.rs package-lock.json tests/native-tree-sitter.test.ts tests/native-parser-ownership.test.ts git commit -m "feat: add graph-first language parsers" ``` @@ -563,8 +561,8 @@ git commit -m "docs: finalize graph-first language support" ## Acceptance Criteria -- All seven languages parse through JS fallback. - All seven languages parse through native runtime, unless a documented grammar compatibility blocker is found and reflected in parity docs. +- All seven languages retain safe reduced-mode behavior when native is unavailable. - File discovery includes the planned extensions. - Each language has a focused `tests/languages/*.test.ts` suite and fixtures. - Each language extracts top-level declarations and static dependency edges listed in this plan. diff --git a/docs/plans/2026-06-06-performance-and-cache-opportunities.md b/docs/plans/2026-06-06-performance-and-cache-opportunities.md index b02d7e28..b568c776 100644 --- a/docs/plans/2026-06-06-performance-and-cache-opportunities.md +++ b/docs/plans/2026-06-06-performance-and-cache-opportunities.md @@ -229,8 +229,8 @@ Implementation checklist: - [x] Define a native API that accepts source text and returns compact duplicate-token preprocessing results. - [x] Start with native tokenization and normalization while keeping shingle/winnow fingerprints and candidate-pair generation in TypeScript. - [x] Keep final reporting, grouping, and CLI JSON schema in TypeScript initially. -- [x] Preserve JS fallback behavior when native is unavailable or disabled. -- [x] Add parity fixtures comparing native and JS fallback duplicate results for exact, renamed, near, and low-confidence cases. +- [x] Preserve reduced-mode behavior when native is unavailable or disabled. +- [x] Add parity fixtures comparing native and reduced-mode duplicate results for exact, renamed, near, and low-confidence cases. - [ ] Add a benchmark fixture with many repeated units and a performance threshold or regression report. Likely files: @@ -429,7 +429,7 @@ Checklist: - [x] Anonymous JS/TS default exports should resolve through default imports. - [x] JS/TS shorthand binding nodes should navigate to the actual binding/import. - [x] Breaking-change suggestions should handle multiline exported signatures. -- [x] Publishing/install docs should clarify that the JS fallback package is only a compatibility shim and does not provide parser recovery. +- [x] Publishing/install docs should clarify that reduced mode has graph-only and regex recovery, not parser recovery. - [x] Consider stable subpath exports before narrowing the broad root API. ## Suggested Execution Order diff --git a/docs/scenario-catalog.md b/docs/scenario-catalog.md index a1424a90..a0d78613 100644 --- a/docs/scenario-catalog.md +++ b/docs/scenario-catalog.md @@ -31,10 +31,10 @@ Minimal catalog of Tree-sitter scenarios with sample coverage. | Scenario | Sample | Expected behavior | Source | Date added | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | ---------- | -| JS fallback compatibility package | `tests/package-metadata.test.ts` | The root package keeps native runtime support as an optional dependency, the native package carries the parser binaries, and the compatibility fallback package ships without a grammar bundle. | Internal regression test | 2026-06-12 | +| Removed JS fallback package | `tests/package-metadata.test.ts`, `tests/release-script.test.ts` | The root package keeps native runtime support as an optional dependency, the native package carries the parser binaries, and the removed compatibility package is neither publishable nor present as a workspace. | Internal regression test | 2026-06-18 | | Reduced-mode recovery | `tests/logging-behavior.test.ts`, `tests/fallback-import-extraction.test.ts` | TypeScript import binding/specifier extraction recovers through regex when native is unavailable, reports reduced-mode recovery, and avoids per-file warning spam. | Internal regression test | 2026-06-12 | -| Native-only source-language runtime coverage | `tests/detailed-symbol-native-only.test.ts`, `tests/chunkFile.behavior.test.ts`, `tests/native-query-scope.test.ts` | Native-loaded source-language indexing, AST grep, chunking, and module-specifier recovery stay off any JS grammar backend when the native addon is loaded, while still reporting degraded recovery in diagnostics. | Internal regression test | 2026-06-12 | -| Native-only source-language semantic coverage | `tests/native-parser-ownership.test.ts` | Native-loaded source-language symbol listing, go-to-definition, find-references, and detailed symbol-edge extraction stay off any JS grammar backend while native mode is active. | Internal regression test | 2026-06-12 | +| Native-only source-language runtime coverage | `tests/detailed-symbol-native-only.test.ts`, `tests/chunkFile.behavior.test.ts`, `tests/native-query-scope.test.ts` | Native-loaded source-language indexing, AST grep, chunking, and module-specifier recovery stay off any non-native parser backend when the native addon is loaded, while still reporting degraded recovery in diagnostics. | Internal regression test | 2026-06-12 | +| Native-only source-language semantic coverage | `tests/native-parser-ownership.test.ts` | Native-loaded source-language symbol listing, go-to-definition, find-references, and detailed symbol-edge extraction stay off any non-native parser backend while native mode is active. | Internal regression test | 2026-06-12 | | Native chunk/query ownership | `tests/native-query-ownership-parity.test.ts` | Native chunking and AST grep stay productive on representative fixtures, while reduced mode remains safe and non-throwing when native is disabled. | Internal regression test | 2026-06-12 | | Native semantic coverage | `tests/native-semantic-parity.test.ts` | Native semantics for representative fixtures stay stable for symbol extraction, go-to-definition, and references across supported source-language samples. | Internal regression test | 2026-06-12 | | Native import/specifier recovery | `tests/native-query-scope.test.ts`, `tests/fallback-import-extraction.test.ts` | Native query normalization stays stable, and reduced mode keeps regex/graph-only recovery limited to the languages and surfaces that explicitly support it. | Internal regression test | 2026-06-12 | diff --git a/package-lock.json b/package-lock.json index 5a421639..d0caba9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -250,7 +250,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -299,11 +298,35 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" } }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", @@ -311,6 +334,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -1411,10 +1435,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@lzehrung/codegraph-js-fallback": { - "resolved": "packages/codegraph-js-fallback", - "link": true - }, "node_modules/@lzehrung/codegraph-native": { "resolved": "packages/codegraph-native", "link": true @@ -2825,7 +2845,6 @@ "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", @@ -3383,7 +3402,6 @@ "integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -3440,7 +3458,6 @@ "integrity": "sha512-nm3cvFN9SqZGXjmw5bZ6cGmvJSyJPn0wU9gHAZZHDnZl2wF9PhHv78Xf06E0MaNk4zLVHL8hb2/c32XvyJOLQg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.53.1", "@typescript-eslint/types": "8.53.1", @@ -3658,7 +3675,6 @@ "integrity": "sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@bcoe/v8-coverage": "^1.0.2", "@vitest/utils": "4.1.8", @@ -3788,7 +3804,6 @@ "integrity": "sha512-RUS2ZU2TsduVrI+9c12uTNaKrNUTsm6yFt3fueEUB9iKvyC2UP83F+sqIz00HQIah4UOL1TMoDAki8K0NjGvsA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/utils": "4.1.8", "fflate": "^0.8.2", @@ -3839,7 +3854,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4552,7 +4566,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4799,7 +4812,6 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -5295,7 +5307,6 @@ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.23.tgz", "integrity": "sha512-eIaZ9qDgu7XV0pxOCrg7/WhnQ6Ivm22UcxhXx/A3dcbqbbYgBEkc6e/J/s7j2tS96zoB0S9VBdLwQNCWwUo4LA==", "license": "MIT", - "peer": true, "engines": { "node": ">=16.9.0" } @@ -7176,7 +7187,6 @@ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" @@ -7251,7 +7261,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7361,7 +7370,6 @@ "integrity": "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", @@ -7440,7 +7448,6 @@ "integrity": "sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/expect": "4.1.8", "@vitest/mocker": "4.1.8", @@ -7670,7 +7677,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -7684,11 +7690,6 @@ "zod": "^3.25.28 || ^4" } }, - "packages/codegraph-js-fallback": { - "name": "@lzehrung/codegraph-js-fallback", - "version": "1.8.62", - "license": "MIT" - }, "packages/codegraph-native": { "name": "@lzehrung/codegraph-native", "version": "1.8.65", diff --git a/packages/codegraph-js-fallback/js-fallback.cjs b/packages/codegraph-js-fallback/js-fallback.cjs deleted file mode 100644 index 985a108f..00000000 --- a/packages/codegraph-js-fallback/js-fallback.cjs +++ /dev/null @@ -1,28 +0,0 @@ -const JS_GRAMMAR_FALLBACK_UNAVAILABLE_MESSAGE = - "JS Tree-sitter fallback is unavailable; native parser is the only grammar backend"; - -function loadTreeSitterLanguage(packageName) { - return { name: packageName }; -} - -function loadTypeScriptGrammars() { - return { - typescript: { name: "tree-sitter-typescript/typescript" }, - tsx: { name: "tree-sitter-typescript/tsx" }, - }; -} - -function parseWithJsLanguage() { - throw new Error(`${JS_GRAMMAR_FALLBACK_UNAVAILABLE_MESSAGE} for syntax-tree parsing`); -} - -function executeJsQueryAsNativeMatches() { - throw new Error(`${JS_GRAMMAR_FALLBACK_UNAVAILABLE_MESSAGE} for query execution`); -} - -module.exports = { - loadTreeSitterLanguage, - loadTypeScriptGrammars, - parseWithJsLanguage, - executeJsQueryAsNativeMatches, -}; diff --git a/packages/codegraph-js-fallback/js-fallback.d.ts b/packages/codegraph-js-fallback/js-fallback.d.ts deleted file mode 100644 index 268bcbbd..00000000 --- a/packages/codegraph-js-fallback/js-fallback.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -export interface JsPoint { - row: number; - column: number; -} - -export interface JsSyntaxNode { - id?: number; - type: string; - text: string; - startIndex: number; - endIndex: number; - startPosition: JsPoint; - endPosition: JsPoint; - parent: JsSyntaxNode | null; - namedChildren: JsSyntaxNode[]; - previousSibling?: JsSyntaxNode | null; - previousNamedSibling?: JsSyntaxNode | null; - child(index: number): JsSyntaxNode | null; - childForFieldName(fieldName: string): JsSyntaxNode | null; -} - -export interface JsSyntaxTree { - rootNode: JsSyntaxNode & { - descendantForIndex(startIndex: number, endIndex: number): JsSyntaxNode; - descendantForPosition(start: JsPoint, end: JsPoint): JsSyntaxNode; - }; - walk(): unknown; -} - -export interface JsLanguage { - readonly name?: string; -} - -export interface JsNativePoint { - row: number; - column: number; - index: number; -} - -export interface JsNativeCapture { - name: string; - text: string; - nodeType: string; - start: JsNativePoint; - end: JsNativePoint; -} - -export interface JsNativeMatch { - patternIndex: number; - captures: JsNativeCapture[]; -} - -export declare function loadTreeSitterLanguage(packageName: string): JsLanguage; -export declare function loadTypeScriptGrammars(): { - typescript: JsLanguage; - tsx: JsLanguage; -}; -export declare function parseWithJsLanguage(source: string, language: JsLanguage): JsSyntaxTree; -export declare function executeJsQueryAsNativeMatches( - source: string, - language: JsLanguage, - queryText: string, - tree?: JsSyntaxTree, -): JsNativeMatch[]; diff --git a/packages/codegraph-js-fallback/package.json b/packages/codegraph-js-fallback/package.json deleted file mode 100644 index aea4009a..00000000 --- a/packages/codegraph-js-fallback/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@lzehrung/codegraph-js-fallback", - "version": "1.8.62", - "description": "Compatibility shim for hosts without a native Codegraph parser backend.", - "main": "./js-fallback.cjs", - "types": "./js-fallback.d.ts", - "exports": { - ".": { - "types": "./js-fallback.d.ts", - "default": "./js-fallback.cjs" - } - }, - "files": [ - "js-fallback.cjs", - "js-fallback.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/lzehrung/codegraph.git", - "directory": "packages/codegraph-js-fallback" - }, - "publishConfig": { - "registry": "https://npm.pkg.github.com" - } -} diff --git a/scripts/patch-tree-sitter-node24-lib.mjs b/scripts/patch-tree-sitter-node24-lib.mjs deleted file mode 100644 index 0b6b20be..00000000 --- a/scripts/patch-tree-sitter-node24-lib.mjs +++ /dev/null @@ -1,87 +0,0 @@ -import { existsSync as fileExistsSync } from "node:fs"; -import { createRequire } from "node:module"; -import path from "node:path"; - -const CXX_STD_VARIABLE = - '"cxxstd%": " - [ - `${indent}"cflags_cc": [`, - `${valueIndent}"-std=<(cxxstd)",`, - `${valueIndent}"-fvisibility=hidden",`, - `${valueIndent}"-Wno-cast-function-type",`, - `${indent}]`, - ].join("\n"), - ); - - patched = replaceRequired( - patched, - "v8_enable_31bit_smis_on_64bit_arch%", - /^([ \t]*)"v8_enable_31bit_smis_on_64bit_arch%"\s*:\s*0,?\s*$/m, - (_match, indent) => `${indent}"v8_enable_31bit_smis_on_64bit_arch%": 0,\n${indent}${CXX_STD_VARIABLE},`, - ); - - return { source: restoreLineEndings(patched, newline), changed: true }; -} diff --git a/scripts/patch-tree-sitter-node24.mjs b/scripts/patch-tree-sitter-node24.mjs deleted file mode 100644 index 4224d714..00000000 --- a/scripts/patch-tree-sitter-node24.mjs +++ /dev/null @@ -1,23 +0,0 @@ -import { readFileSync, writeFileSync } from "node:fs"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import { patchTreeSitterBindingGypSource, resolveTreeSitterBindingGypPath } from "./patch-tree-sitter-node24-lib.mjs"; - -const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); -const bindingPath = resolveTreeSitterBindingGypPath({ repoRoot }); - -if (!bindingPath) { - console.log("[codegraph] tree-sitter binding.gyp was not found; skipping Node 24 patch."); - process.exit(0); -} - -const original = readFileSync(bindingPath, "utf8"); -const result = patchTreeSitterBindingGypSource(original); - -if (!result.changed) { - console.log("[codegraph] tree-sitter binding.gyp already selects the C++ standard dynamically."); - process.exit(0); -} - -writeFileSync(bindingPath, result.source); -console.log("[codegraph] Patched tree-sitter binding.gyp for Node 24 C++20 builds."); diff --git a/scripts/release-lib.mjs b/scripts/release-lib.mjs index 5f8f1b02..cc86dd45 100644 --- a/scripts/release-lib.mjs +++ b/scripts/release-lib.mjs @@ -33,14 +33,6 @@ export const releasePackages = [ ownedFiles: new Set([]), ownedPrefixes: ["packages/codegraph-native/"], }, - { - id: "js-fallback", - name: "@lzehrung/codegraph-js-fallback", - manifestPath: "packages/codegraph-js-fallback/package.json", - publishWorkspace: "@lzehrung/codegraph-js-fallback", - ownedFiles: new Set([]), - ownedPrefixes: ["packages/codegraph-js-fallback/"], - }, ]; export const managedReleasePaths = new Set([ @@ -205,29 +197,12 @@ export function computePublishExecutionSteps(publishPlan) { if (publishPlan.publishByPackage["@lzehrung/codegraph-native"]) { steps.push("publishNativeTargets", "prepareNativeMeta", "publishNativeMeta"); } - if (publishPlan.publishByPackage["@lzehrung/codegraph-js-fallback"]) { - steps.push("publishJsFallback"); - } if (publishPlan.publishByPackage["@lzehrung/codegraph"]) { steps.push("prepareRootManifest", "publishRoot"); } return steps; } -export function sanitizeJsFallbackPackageManifest(pkg) { - const normalized = { ...pkg }; - if ( - normalized.dependencies && - typeof normalized.dependencies === "object" && - !Array.isArray(normalized.dependencies) - ) { - const dependencies = { ...normalized.dependencies }; - delete dependencies["@lzehrung/codegraph"]; - normalized.dependencies = dependencies; - } - return normalized; -} - export function sanitizePublishedRootPackageManifest(pkg) { const normalized = { ...pkg }; delete normalized.devDependencies; diff --git a/scripts/release.mjs b/scripts/release.mjs index 7dcce7a3..1eb5db48 100644 --- a/scripts/release.mjs +++ b/scripts/release.mjs @@ -17,7 +17,6 @@ import { restoreRootPackageManifest, restoreNativePackageManifest, sanitizePublishedRootPackageManifest, - sanitizeJsFallbackPackageManifest, selectLatestLegacyTag, selectLatestSemverTag, tagNamesForPackageVersion, @@ -29,7 +28,6 @@ const rootDir = process.cwd(); const rootPackagePath = path.join(rootDir, "package.json"); const nativeRootPath = path.join(rootDir, "packages", "codegraph-native"); const nativePackagePath = path.join(rootDir, "packages", "codegraph-native", "package.json"); -const jsFallbackPackagePath = path.join(rootDir, "packages", "codegraph-js-fallback", "package.json"); const currentRootPackage = readJson(rootPackagePath); const currentNativePackage = readJson(nativePackagePath); const originalRootPackageJson = `${JSON.stringify( @@ -163,11 +161,9 @@ function readCurrentPackageVersions() { function normalizeManagedManifests(versionPlan) { let rootPackage = JSON.parse(originalRootPackageJson); const nativePackage = JSON.parse(originalNativePackageJson); - const jsFallbackPackage = sanitizeJsFallbackPackageManifest(readJson(jsFallbackPackagePath)); const rootVersion = versionPlan.get("root"); const nativeVersion = versionPlan.get("native"); - const jsFallbackVersion = versionPlan.get("js-fallback"); if (rootVersion) { rootPackage.version = rootVersion; @@ -175,9 +171,6 @@ function normalizeManagedManifests(versionPlan) { if (nativeVersion) { nativePackage.version = nativeVersion; } - if (jsFallbackVersion) { - jsFallbackPackage.version = jsFallbackVersion; - } if (rootVersion) { rootPackage = restoreRootPackageManifest(rootPackage, rootVersion, nativePackage.version); } @@ -187,7 +180,6 @@ function normalizeManagedManifests(versionPlan) { writeJson(rootPackagePath, rootPackage); writeJson(nativePackagePath, nativePackage); - writeJson(jsFallbackPackagePath, jsFallbackPackage); } function restoreNativePackage(versionPlan) { @@ -335,13 +327,7 @@ function planVersions(selectedPackages, currentVersions, { releaseType, shouldRe } function commitAndTag(selectedPackages, versionPlan) { - runGit([ - "add", - "package.json", - "package-lock.json", - "packages/codegraph-native/package.json", - "packages/codegraph-js-fallback/package.json", - ]); + runGit(["add", "package.json", "package-lock.json", "packages/codegraph-native/package.json"]); const commitNeeded = spawnSync("git", ["diff", "--cached", "--quiet"], { cwd: rootDir, @@ -392,7 +378,7 @@ const shouldResume = releaseType === "resume"; if (!shouldResume && !validReleaseTypes.has(releaseType)) { console.error( - "Usage: node ./scripts/release.mjs [--publish] [--package ]", + "Usage: node ./scripts/release.mjs [--publish] [--package ]", ); process.exit(1); } @@ -460,10 +446,6 @@ if (publishPlan) { run("npm", ["run", "publish:native:meta"]); continue; } - if (step === "publishJsFallback") { - run("npm", ["publish", "--workspace=@lzehrung/codegraph-js-fallback"]); - continue; - } if (step === "prepareRootManifest") { writePublishReadyRootPackage(versionPlan); continue; diff --git a/src/graph-edge-collector.ts b/src/graph-edge-collector.ts index 3cb9adb6..64c81818 100644 --- a/src/graph-edge-collector.ts +++ b/src/graph-edge-collector.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { type JsLanguage } from "./jsFallback.js"; +import { type ParserLanguage } from "./parserBackend.js"; import { prepareSourceInput } from "./languages/filePrep.js"; import { type LanguageSupport } from "./languages.js"; import type { Edge } from "./types.js"; @@ -40,7 +40,7 @@ export async function collectEdgesForFile( source: string; tree?: SyntaxTreeLike; sup: LanguageSupport; - lang?: JsLanguage; + lang?: ParserLanguage; nativeQueries?: NativeQueryResults | null; }; fast?: boolean; diff --git a/src/indexer.ts b/src/indexer.ts index 09b3b756..bc0e8738 100644 --- a/src/indexer.ts +++ b/src/indexer.ts @@ -67,10 +67,10 @@ import { } from "./indexer/types.js"; import { buildScopeIndexFromSource as buildScopeIndexFromSourceFromModule, type ScopeIndex } from "./indexer/scope.js"; import type { LanguageSupport } from "./languages.js"; -import type { JsLanguage, SyntaxTreeLike } from "./languages/types.js"; +import type { ParserLanguage, SyntaxTreeLike } from "./languages/types.js"; import type { NativeQueryResults, NativeRuntimeMode } from "./native/treeSitterNative.js"; import type { FileId } from "./types.js"; -import type { JsSyntaxTree } from "./jsFallback.js"; +import type { ParserSyntaxTree } from "./parserBackend.js"; export { SymbolKind } from "./indexer/types.js"; export type { @@ -135,7 +135,7 @@ export function collectLocalsAndExportsFromSource( file: string, source: string, support: LanguageSupport, - lang?: JsLanguage, + lang?: ParserLanguage, imports: ImportBinding[] = [], opts?: { tree?: SyntaxTreeLike; @@ -152,9 +152,9 @@ export async function collectImportsForFile( projectRoot: string, opts?: { source?: string; - tree?: JsSyntaxTree; + tree?: ParserSyntaxTree; sup?: LanguageSupport; - lang?: JsLanguage; + lang?: ParserLanguage; nativeQueries?: NativeQueryResults | null; graphOptions?: GraphBuildOptions; native?: import("./native/treeSitterNative.js").NativeRuntimeMode; @@ -180,7 +180,7 @@ export function buildScopeIndexFromSource( file: string, source: string, support: LanguageSupport, - lang?: JsLanguage, + lang?: ParserLanguage, imports: ImportBinding[] = [], opts?: { tree?: SyntaxTreeLike; nativeMode?: NativeRuntimeMode }, ): ScopeIndex { diff --git a/src/indexer/build-index.ts b/src/indexer/build-index.ts index 74ca1b46..af443794 100644 --- a/src/indexer/build-index.ts +++ b/src/indexer/build-index.ts @@ -23,7 +23,7 @@ import { buildBloomFilterFromSource } from "../util/bloomFilter.js"; import { initNativeBackendReport } from "../native/nativeBackendReport.js"; import { closeDuplicateUnitCacheDatabase } from "../duplicates.js"; import { isNativeRequiredUnavailableError } from "../native/treeSitterNative.js"; -import type { JsLanguage, SyntaxTreeLike } from "../languages/types.js"; +import type { ParserLanguage, SyntaxTreeLike } from "../languages/types.js"; import type { Edge, FileId, Graph } from "../types.js"; import { buildBloomFilterForFile, @@ -67,7 +67,7 @@ import { type SymbolDef, SymbolKind, } from "./types.js"; -import { isJsFallbackUnavailableError, isJsSyntaxTree } from "../jsFallback.js"; +import { isNonNativeParserUnavailableError, isParserSyntaxTree } from "../parserBackend.js"; import { isUnsupportedParserInputError } from "../languages/filePrep.js"; import { buildSqlFactCache, buildSqlModuleIndex, sqlCorpusSignature, type SqlFactCache } from "../sql/sourceGraph.js"; import { finalizeProjectIndex } from "./finalize.js"; @@ -89,7 +89,7 @@ import { parsedCacheMaxEntries, setParsedCacheEntry } from "./parsed-cache.js"; type IndexedFileGraphContext = { source: string; sup: LanguageSupport; - lang?: JsLanguage; + lang?: ParserLanguage; nativeQueries?: import("../native/treeSitterNative.js").NativeQueryResults | null; tree?: SyntaxTreeLike; }; @@ -231,7 +231,7 @@ async function buildIndexedModuleForFile(args: { ? [] : await collectImportsForFile(args.file, args.projectRoot, { source, - ...(tree && isJsSyntaxTree(tree) ? { tree } : {}), + ...(tree && isParserSyntaxTree(tree) ? { tree } : {}), sup, ...(resolvedLang ? { lang: resolvedLang } : {}), ...(nativeQueries !== undefined ? { nativeQueries } : {}), @@ -663,7 +663,7 @@ async function buildIndexFromFileListShared( return [file, mod ?? createEmptyModuleIndex(file), edges] as const; } catch (error) { if (isNativeRequiredUnavailableError(error)) throw error; - if (isUnsupportedParserInputError(error) || isJsFallbackUnavailableError(error)) { + if (isUnsupportedParserInputError(error) || isNonNativeParserUnavailableError(error)) { return [file, createEmptyModuleIndex(file), []] as const; } recordFileFailure(report, file, error); @@ -1068,7 +1068,7 @@ export async function buildProjectIndexIncremental( return [file, built.module] as const; } catch (error) { if (isNativeRequiredUnavailableError(error)) throw error; - if (isUnsupportedParserInputError(error) || isJsFallbackUnavailableError(error)) { + if (isUnsupportedParserInputError(error) || isNonNativeParserUnavailableError(error)) { return [file, createEmptyModuleIndex(file)] as const; } recordFileFailure(report, file, error); diff --git a/src/indexer/imports.ts b/src/indexer/imports.ts index 06192b33..c2c56bd4 100644 --- a/src/indexer/imports.ts +++ b/src/indexer/imports.ts @@ -18,7 +18,7 @@ import { } from "../native/treeSitterNative.js"; import type { ResolvedImportTarget } from "./imports/context.js"; import { collectGraphOnlyImports } from "./imports/graphOnly.js"; -import { collectJsTextImports, collectJsTextValueRequireImports } from "./imports/jsFallback.js"; +import { collectJsTextImports, collectJsTextValueRequireImports } from "./imports/jsTextImports.js"; import { applyStatementImportOverride, createStatementImportOverrideState, @@ -27,7 +27,7 @@ import { import { collectNativeCaptureImportBindings } from "./imports/nativeCaptures.js"; import { collectPythonImportsFromSource } from "./imports/python.js"; import type { LanguageSupport } from "../languages.js"; -import type { JsLanguage, SyntaxTreeLike } from "../languages/types.js"; +import type { ParserLanguage, SyntaxTreeLike } from "../languages/types.js"; import type { ImportBinding } from "./types.js"; export async function collectImportsForFile( @@ -37,7 +37,7 @@ export async function collectImportsForFile( source?: string; tree?: SyntaxTreeLike; sup?: LanguageSupport; - lang?: JsLanguage; + lang?: ParserLanguage; nativeQueries?: NativeQueryResults | null; graphOptions?: GraphBuildOptions; native?: NativeRuntimeMode; diff --git a/src/indexer/imports/jsFallback.ts b/src/indexer/imports/jsTextImports.ts similarity index 100% rename from src/indexer/imports/jsFallback.ts rename to src/indexer/imports/jsTextImports.ts diff --git a/src/indexer/imports/nativeCaptures.ts b/src/indexer/imports/nativeCaptures.ts index 507d154b..fad8b7c8 100644 --- a/src/indexer/imports/nativeCaptures.ts +++ b/src/indexer/imports/nativeCaptures.ts @@ -1,4 +1,4 @@ -import type { JsSyntaxTree } from "../../jsFallback.js"; +import type { ParserSyntaxTree } from "../../parserBackend.js"; import { capturesByName, capturesNamed, rangeFromNativeCapture } from "../../native/queryResults.js"; import type { NativeCapture, NativeMatch } from "../../native/treeSitterNative.js"; import { sliceText, unquote } from "../../util/ast.js"; @@ -64,7 +64,7 @@ async function pushTextObjectPatternBindings( async function pushTreeObjectPatternBindings( context: ImportCaptureExtractionContext, - tree: JsSyntaxTree, + tree: ParserSyntaxTree, patterns: NativeCapture[], from: string | undefined, typeOnly: boolean, @@ -225,7 +225,7 @@ export async function collectNativeCaptureImportBindings( export async function collectJsQueryCaptureImportBindings( context: ImportCaptureExtractionContext, matches: NativeMatch[], - tree: JsSyntaxTree, + tree: ParserSyntaxTree, ): Promise { for (const match of matches) { const caps = capturesByName(match); diff --git a/src/indexer/locals-and-exports.ts b/src/indexer/locals-and-exports.ts index 56772120..59e86860 100644 --- a/src/indexer/locals-and-exports.ts +++ b/src/indexer/locals-and-exports.ts @@ -17,7 +17,7 @@ import { buildScopeIndexFromSource } from "./scope.js"; import { QUERY_DRIVEN_LOCALS_LANGUAGES } from "./shared.js"; import { SymbolKind } from "./types.js"; import type { LanguageSupport } from "../languages.js"; -import type { JsLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; +import type { ParserLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; import type { ExportEntry, ImportBinding, ModuleIndex, SymbolDef } from "./types.js"; import type { Range } from "../types.js"; @@ -193,7 +193,7 @@ export function collectLocalsAndExportsFromSource( file: string, source: string, support: LanguageSupport, - lang?: JsLanguage, + lang?: ParserLanguage, imports: ImportBinding[] = [], opts?: { tree?: SyntaxTreeLike; diff --git a/src/indexer/navigation-local.ts b/src/indexer/navigation-local.ts index d8a7dd1c..c59d2b86 100644 --- a/src/indexer/navigation-local.ts +++ b/src/indexer/navigation-local.ts @@ -1,5 +1,5 @@ import type { LanguageSupport } from "../languages.js"; -import type { JsLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; +import type { ParserLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; import type { FileId } from "../types.js"; import { okGoToResult } from "./navigation-provenance.js"; import { buildScopeIndexFromSource, type ScopeIndex } from "./scope.js"; @@ -43,7 +43,7 @@ export function getOrBuildScopeIndex( file: FileId, source: string, sup: LanguageSupport, - lang: JsLanguage | undefined, + lang: ParserLanguage | undefined, mod: ModuleIndex, tree: SyntaxTreeLike, ): ScopeIndex { diff --git a/src/indexer/navigation-provenance.ts b/src/indexer/navigation-provenance.ts index 95b85515..3a178adb 100644 --- a/src/indexer/navigation-provenance.ts +++ b/src/indexer/navigation-provenance.ts @@ -9,7 +9,7 @@ function getNavigationBackend(index: ProjectIndex): ResolutionProvenance["backen return "native"; } if (index.nativeMode === "off") { - return "js-fallback"; + return "graph-only"; } return undefined; } diff --git a/src/indexer/navigation-references.ts b/src/indexer/navigation-references.ts index fe35ac53..65c83efc 100644 --- a/src/indexer/navigation-references.ts +++ b/src/indexer/navigation-references.ts @@ -1,5 +1,5 @@ import type { LanguageSupport } from "../languages.js"; -import type { JsLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; +import type { ParserLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; import type { Range } from "../types.js"; import { sliceText, toRange } from "../util/ast.js"; import { ensureParsedContext } from "./parse-context.js"; @@ -18,7 +18,7 @@ export function getCachedScope( parsedCtx: { source: string; sup: LanguageSupport; - lang?: JsLanguage; + lang?: ParserLanguage; tree: SyntaxTreeLike; }, ): ScopeIndex { diff --git a/src/indexer/parse-context.ts b/src/indexer/parse-context.ts index 6eb86565..b9bde573 100644 --- a/src/indexer/parse-context.ts +++ b/src/indexer/parse-context.ts @@ -9,13 +9,13 @@ import { import type { NativeFallbackReason } from "../native/contracts.js"; import { ProjectedSyntaxTree } from "../native/projectedTree.js"; import type { LanguageSupport } from "../languages.js"; -import type { JsLanguage, SyntaxTreeLike } from "../languages/types.js"; +import type { ParserLanguage, SyntaxTreeLike } from "../languages/types.js"; export type ParsedFileContext = { source: string; tree: SyntaxTreeLike; sup: LanguageSupport; - lang?: JsLanguage; + lang?: ParserLanguage; nativeQueries?: NativeQueryResults | null; }; @@ -23,7 +23,7 @@ export type ParsedFileCacheEntry = { source: string; tree: SyntaxTreeLike; sup: LanguageSupport | undefined; - lang?: JsLanguage; + lang?: ParserLanguage; nativeQueries?: NativeQueryResults | null; }; @@ -31,7 +31,7 @@ export type PreparedFileContext = { file: string; source: string; sup: LanguageSupport; - lang?: JsLanguage; + lang?: ParserLanguage; nativeMode?: NativeRuntimeMode; nativeQueries: NativeQueryResults | null; nativeFallbackReason?: NativeFallbackReason; diff --git a/src/indexer/scope.ts b/src/indexer/scope.ts index 4b5b24ea..5219c28f 100644 --- a/src/indexer/scope.ts +++ b/src/indexer/scope.ts @@ -3,7 +3,7 @@ import { getNativeSyntaxTreeExecution, type NativeRuntimeMode } from "../native/ import { ProjectedSyntaxTree } from "../native/projectedTree.js"; import { declarationKindToBindingKind } from "./declarations.js"; import type { LanguageSupport } from "../languages.js"; -import type { JsLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; +import type { ParserLanguage, SyntaxNodeLike, SyntaxTreeLike } from "../languages/types.js"; import type { Range } from "../types.js"; import type { ImportBinding } from "./types.js"; import type { Binding, BindingKind, Scope, ScopeIndex } from "./scope-types.js"; @@ -14,7 +14,7 @@ export function buildScopeIndexFromSource( file: string, source: string, support: LanguageSupport, - lang?: JsLanguage, + lang?: ParserLanguage, imports: ImportBinding[] = [], opts?: { tree?: SyntaxTreeLike; nativeMode?: NativeRuntimeMode }, ): ScopeIndex { diff --git a/src/indexer/types.ts b/src/indexer/types.ts index 100343f7..13b86ba4 100644 --- a/src/indexer/types.ts +++ b/src/indexer/types.ts @@ -300,7 +300,7 @@ export type ApiSurface = Array<{ export type GoToRequest = { file: FileId; line: number; column: number }; export type ResolutionProvenance = { - backend?: "native" | "js-fallback" | "graph-only" | "heuristic"; + backend?: "native" | "graph-only" | "heuristic"; resolution?: "exact" | "import" | "import-star" | "namespace" | "reexport" | "php-qualified" | "member-access"; confidence?: "high" | "medium" | "low"; }; diff --git a/src/jsFallback.ts b/src/jsFallback.ts deleted file mode 100644 index cb84ef11..00000000 --- a/src/jsFallback.ts +++ /dev/null @@ -1,101 +0,0 @@ -export interface JsPoint { - row: number; - column: number; -} - -export interface JsSyntaxNode { - readonly id?: number; - type: string; - text: string; - startIndex: number; - endIndex: number; - startPosition: JsPoint; - endPosition: JsPoint; - parent: JsSyntaxNode | null; - namedChildren: JsSyntaxNode[]; - previousSibling?: JsSyntaxNode | null; - previousNamedSibling?: JsSyntaxNode | null; - child(index: number): JsSyntaxNode | null; - childForFieldName(fieldName: string): JsSyntaxNode | null; -} - -export interface JsSyntaxTree { - rootNode: JsSyntaxNode & { - descendantForIndex(startIndex: number, endIndex: number): JsSyntaxNode; - descendantForPosition(start: JsPoint, end: JsPoint): JsSyntaxNode; - }; - walk(): unknown; -} - -export interface JsLanguage { - readonly name?: string; -} - -export interface JsNativePoint { - row: number; - column: number; - index: number; -} - -export interface JsNativeCapture { - name: string; - text: string; - nodeType: string; - start: JsNativePoint; - end: JsNativePoint; -} - -export interface JsNativeMatch { - patternIndex: number; - captures: JsNativeCapture[]; -} - -const JS_GRAMMAR_FALLBACK_UNAVAILABLE_MESSAGE = - "JS Tree-sitter fallback is unavailable; native parser is the only grammar backend"; - -function createUnavailableError(feature: string): Error { - return new Error(`${JS_GRAMMAR_FALLBACK_UNAVAILABLE_MESSAGE} for ${feature}`); -} - -export function __resetJsFallbackModuleForTests(): void { - // Kept for tests that reset parser backends between cases. -} - -export function isJsFallbackAvailable(): boolean { - return false; -} - -export function isJsFallbackUnavailableError(error: unknown): boolean { - return error instanceof Error && error.message.includes("JS Tree-sitter fallback is unavailable"); -} - -export function loadTreeSitterLanguage(packageName: string): JsLanguage { - return { name: packageName }; -} - -export function loadTypeScriptGrammars(): { - typescript: JsLanguage; - tsx: JsLanguage; -} { - return { - typescript: { name: "tree-sitter-typescript/typescript" }, - tsx: { name: "tree-sitter-typescript/tsx" }, - }; -} - -export function parseWithJsLanguage(_source: string, _language: JsLanguage): JsSyntaxTree { - throw createUnavailableError("syntax-tree parsing"); -} - -export function isJsSyntaxTree(tree: unknown): tree is JsSyntaxTree { - return typeof tree === "object" && tree !== null && "rootNode" in tree && "walk" in tree; -} - -export function executeJsQueryAsNativeMatches( - _source: string, - _language: JsLanguage, - _queryText: string, - _tree?: JsSyntaxTree, -): JsNativeMatch[] { - throw createUnavailableError("query execution"); -} diff --git a/src/languages.ts b/src/languages.ts index bef8043f..57fe8a4b 100644 --- a/src/languages.ts +++ b/src/languages.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import path from "node:path"; -import type { LanguageDefinition, JsLanguage, NativeCompatibility, SyntaxNodeLike } from "./languages/types.js"; +import type { LanguageDefinition, ParserLanguage, NativeCompatibility, SyntaxNodeLike } from "./languages/types.js"; import { getAllLanguages, getLanguageById } from "./languages/registry.js"; import "./languages/all.js"; @@ -9,7 +9,7 @@ export type IdentifierNodeType = string; export type LanguageSupport = { id: string; matchExts: string[]; - language: (filename: string) => JsLanguage; + language: (filename: string) => ParserLanguage; nodeTypes: { identifier: IdentifierNodeType[]; propertyIdentifier?: IdentifierNodeType[]; @@ -82,7 +82,7 @@ export function supportForFile(filename: string): LanguageSupport | undefined { } return LANGUAGE_SUPPORTS.find((s) => s.matchExts.includes(ext)); } -export function languageForFile(filename: string): JsLanguage { +export function languageForFile(filename: string): ParserLanguage { const sup = supportForFile(filename); if (!sup) throw new Error(`Unsupported file extension: ${filename}`); return sup.language(filename); diff --git a/src/languages/definitions/loadLanguage.ts b/src/languages/definitions/loadLanguage.ts index 08c8e056..bd102be8 100644 --- a/src/languages/definitions/loadLanguage.ts +++ b/src/languages/definitions/loadLanguage.ts @@ -1 +1 @@ -export { loadTreeSitterLanguage, loadTypeScriptGrammars } from "../../jsFallback.js"; +export { loadTreeSitterLanguage, loadTypeScriptGrammars } from "../../parserBackend.js"; diff --git a/src/languages/filePrep.ts b/src/languages/filePrep.ts index f1ebd5bb..5e55b262 100644 --- a/src/languages/filePrep.ts +++ b/src/languages/filePrep.ts @@ -1,5 +1,5 @@ import fsp from "node:fs/promises"; -import type { JsLanguage } from "../languages/types.js"; +import type { ParserLanguage } from "../languages/types.js"; import { JS_SUPPORT, @@ -14,7 +14,7 @@ import { prepareSFCScriptSource, detectSFCFramework, type SFCFramework } from ". interface ParserInput { source: string; sup: LanguageSupport; - lang: JsLanguage; + lang: ParserLanguage; } interface SourceInput { diff --git a/src/languages/types.ts b/src/languages/types.ts index 3ec167c4..920f55ca 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -1,8 +1,8 @@ -import type { JsLanguage, JsPoint, JsSyntaxNode } from "../jsFallback.js"; -export type { JsLanguage }; +import type { ParserLanguage, ParserSyntaxNode, SyntaxPoint } from "../parserBackend.js"; +export type { ParserLanguage }; -export type SyntaxPositionLike = JsPoint; -export type SyntaxNodeLike = JsSyntaxNode; +export type SyntaxPositionLike = SyntaxPoint; +export type SyntaxNodeLike = ParserSyntaxNode; export interface SyntaxTreeLike { rootNode: SyntaxNodeLike & { descendantForIndex(startIndex: number, endIndex: number): SyntaxNodeLike; @@ -23,7 +23,7 @@ export interface NativeCompatibility { export interface LanguageDefinition { id: string; extensions: string[]; - grammar: (filename?: string) => JsLanguage; + grammar: (filename?: string) => ParserLanguage; /** * Configuration for semantic chunking. diff --git a/src/parserBackend.ts b/src/parserBackend.ts new file mode 100644 index 00000000..7eacba74 --- /dev/null +++ b/src/parserBackend.ts @@ -0,0 +1,101 @@ +export interface SyntaxPoint { + row: number; + column: number; +} + +export interface ParserSyntaxNode { + readonly id?: number; + type: string; + text: string; + startIndex: number; + endIndex: number; + startPosition: SyntaxPoint; + endPosition: SyntaxPoint; + parent: ParserSyntaxNode | null; + namedChildren: ParserSyntaxNode[]; + previousSibling?: ParserSyntaxNode | null; + previousNamedSibling?: ParserSyntaxNode | null; + child(index: number): ParserSyntaxNode | null; + childForFieldName(fieldName: string): ParserSyntaxNode | null; +} + +export interface ParserSyntaxTree { + rootNode: ParserSyntaxNode & { + descendantForIndex(startIndex: number, endIndex: number): ParserSyntaxNode; + descendantForPosition(start: SyntaxPoint, end: SyntaxPoint): ParserSyntaxNode; + }; + walk(): unknown; +} + +export interface ParserLanguage { + readonly name?: string; +} + +export interface QueryPoint { + row: number; + column: number; + index: number; +} + +export interface QueryCapture { + name: string; + text: string; + nodeType: string; + start: QueryPoint; + end: QueryPoint; +} + +export interface QueryMatch { + patternIndex: number; + captures: QueryCapture[]; +} + +const NON_NATIVE_PARSER_UNAVAILABLE_MESSAGE = + "Non-native Tree-sitter parser is unavailable; native parser is the only grammar backend"; + +function createUnavailableError(feature: string): Error { + return new Error(`${NON_NATIVE_PARSER_UNAVAILABLE_MESSAGE} for ${feature}`); +} + +export function __resetParserBackendModuleForTests(): void { + // Kept for tests that reset parser backends between cases. +} + +export function isNonNativeParserAvailable(): boolean { + return false; +} + +export function isNonNativeParserUnavailableError(error: unknown): boolean { + return error instanceof Error && error.message.includes(NON_NATIVE_PARSER_UNAVAILABLE_MESSAGE); +} + +export function loadTreeSitterLanguage(packageName: string): ParserLanguage { + return { name: packageName }; +} + +export function loadTypeScriptGrammars(): { + typescript: ParserLanguage; + tsx: ParserLanguage; +} { + return { + typescript: { name: "tree-sitter-typescript/typescript" }, + tsx: { name: "tree-sitter-typescript/tsx" }, + }; +} + +export function parseWithLanguage(_source: string, _language: ParserLanguage): ParserSyntaxTree { + throw createUnavailableError("syntax-tree parsing"); +} + +export function isParserSyntaxTree(tree: unknown): tree is ParserSyntaxTree { + return typeof tree === "object" && tree !== null && "rootNode" in tree && "walk" in tree; +} + +export function executeQueryAsNativeMatches( + _source: string, + _language: ParserLanguage, + _queryText: string, + _tree?: ParserSyntaxTree, +): QueryMatch[] { + throw createUnavailableError("query execution"); +} diff --git a/tests/detailed-symbol-native-only.test.ts b/tests/detailed-symbol-native-only.test.ts index 3775ae91..da8086eb 100644 --- a/tests/detailed-symbol-native-only.test.ts +++ b/tests/detailed-symbol-native-only.test.ts @@ -3,7 +3,7 @@ import path from "node:path"; import os from "node:os"; import fsp from "node:fs/promises"; import { buildProjectIndex } from "../src/indexer.js"; -import { createUnavailableJsFallbackSpies, expectJsFallbackUnusedForNativeOwnership } from "./helpers/native.js"; +import { createUnavailableParserBackendSpies, expectParserBackendUnusedForNativeOwnership } from "./helpers/native.js"; async function mkTmpDir(prefix: string): Promise { return await fsp.mkdtemp(path.join(os.tmpdir(), prefix)); @@ -15,7 +15,7 @@ describe("detailed symbol graph in native-only installs", () => { afterEach(() => { vi.restoreAllMocks(); vi.resetModules(); - vi.doUnmock("../src/jsFallback.js"); + vi.doUnmock("../src/parserBackend.js"); vi.doUnmock("../src/native/treeSitterNative.js"); }); @@ -32,15 +32,15 @@ describe("detailed symbol graph in native-only installs", () => { index.parsed = new Map(); const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - const fallbackSpies = createUnavailableJsFallbackSpies("grammar"); + const fallbackSpies = createUnavailableParserBackendSpies("grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: fallbackSpies.parseSpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: fallbackSpies.parseSpy, }; }); vi.doMock("../src/native/treeSitterNative.js", async () => { @@ -60,7 +60,7 @@ describe("detailed symbol graph in native-only installs", () => { const detailed = await buildSymbolGraphDetailed(index); const warnings = warnSpy.mock.calls.map((call) => String(call[0] ?? "")); - expectJsFallbackUnusedForNativeOwnership({ parseSpy: fallbackSpies.parseSpy }); + expectParserBackendUnusedForNativeOwnership({ parseSpy: fallbackSpies.parseSpy }); expect(warnings.some((warning) => warning.includes("Failed to build detailed symbol edges for"))).toBe(false); expect(warnings).toContain( "Warning: Skipped detailed symbol edges for 1 file(s) because no syntax-tree backend was available.", @@ -77,14 +77,14 @@ describe("detailed symbol graph in native-only installs", () => { ); const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); - const fallbackSpies = createUnavailableJsFallbackSpies("grammar"); + const fallbackSpies = createUnavailableParserBackendSpies("grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - parseWithJsLanguage: fallbackSpies.parseSpy, + parseWithLanguage: fallbackSpies.parseSpy, }; }); vi.doMock("../src/native/treeSitterNative.js", async () => { @@ -110,7 +110,7 @@ describe("detailed symbol graph in native-only installs", () => { const warnings = warnSpy.mock.calls.map((call) => String(call[0] ?? "")); expect(index.byFile.size).toBe(1); expect(index.byFile.get(normalizePath(path.join(root, "legacy.js")))).toBeDefined(); - expectJsFallbackUnusedForNativeOwnership({ parseSpy: fallbackSpies.parseSpy }); + expectParserBackendUnusedForNativeOwnership({ parseSpy: fallbackSpies.parseSpy }); expect(report.backend?.parser?.total).toBe(1); expect(report.backend?.parser?.byLanguage.js).toBe(1); expect(report.backend?.parser?.files).toContainEqual( @@ -123,7 +123,7 @@ describe("detailed symbol graph in native-only installs", () => { expect(warnings.some((warning) => warning.includes("Warning: Failed to process file"))).toBe(false); }); - it("recovers TypeScript imports without loading the JS fallback package", async () => { + it("recovers TypeScript imports without loading a non-native parser", async () => { const root = await mkTmpDir("cg-ts-imports-native-only-"); const entryFile = path.join(root, "entry.ts"); const depFile = path.join(root, "dep.ts"); @@ -134,16 +134,16 @@ describe("detailed symbol graph in native-only installs", () => { ); await fsp.writeFile(depFile, ["export default 1;", "export const helper = 2;", ""].join("\n"), "utf8"); - const fallbackSpies = createUnavailableJsFallbackSpies("TypeScript grammar"); + const fallbackSpies = createUnavailableParserBackendSpies("TypeScript grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: fallbackSpies.parseSpy, - executeJsQueryAsNativeMatches: fallbackSpies.querySpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: fallbackSpies.parseSpy, + executeQueryAsNativeMatches: fallbackSpies.querySpy, }; }); @@ -183,24 +183,24 @@ describe("detailed symbol graph in native-only installs", () => { typeOnly: false, }, ]); - expectJsFallbackUnusedForNativeOwnership(fallbackSpies); + expectParserBackendUnusedForNativeOwnership(fallbackSpies); }); - it("recovers Kotlin alias imports without loading the JS fallback package", async () => { + it("recovers Kotlin alias imports without loading a non-native parser", async () => { const root = path.resolve(process.cwd(), "tests", "samples", "kotlin"); const entryFile = path.join(root, "Aliases.kt"); const depFile = path.join(root, "utils", "helperFunction.kt"); - const fallbackSpies = createUnavailableJsFallbackSpies("Kotlin grammar"); + const fallbackSpies = createUnavailableParserBackendSpies("Kotlin grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: fallbackSpies.parseSpy, - executeJsQueryAsNativeMatches: fallbackSpies.querySpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: fallbackSpies.parseSpy, + executeQueryAsNativeMatches: fallbackSpies.querySpy, }; }); @@ -223,10 +223,10 @@ describe("detailed symbol graph in native-only installs", () => { typeOnly: false, }, ]); - expectJsFallbackUnusedForNativeOwnership(fallbackSpies); + expectParserBackendUnusedForNativeOwnership(fallbackSpies); }); - it("indexes TypeScript locals and exports without loading the JS fallback package", async () => { + it("indexes TypeScript locals and exports without loading a non-native parser", async () => { const root = await mkTmpDir("cg-ts-index-native-only-"); const entryFile = path.join(root, "entry.ts"); await fsp.writeFile( @@ -243,16 +243,16 @@ describe("detailed symbol graph in native-only installs", () => { "utf8", ); - const fallbackSpies = createUnavailableJsFallbackSpies("TypeScript grammar"); + const fallbackSpies = createUnavailableParserBackendSpies("TypeScript grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: fallbackSpies.parseSpy, - executeJsQueryAsNativeMatches: fallbackSpies.querySpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: fallbackSpies.parseSpy, + executeQueryAsNativeMatches: fallbackSpies.querySpy, }; }); @@ -269,10 +269,10 @@ describe("detailed symbol graph in native-only installs", () => { expect(moduleIndex?.exports.filter((entry) => entry.type === "local").map((entry) => entry.exportedAs)).toEqual( expect.arrayContaining(["Service", "helper"]), ); - expectJsFallbackUnusedForNativeOwnership(fallbackSpies); + expectParserBackendUnusedForNativeOwnership(fallbackSpies); }); - it("runs TypeScript AST grep without loading the JS fallback package", async () => { + it("runs TypeScript AST grep without loading a non-native parser", async () => { const root = await mkTmpDir("cg-ts-grep-native-only-"); const entryFile = path.join(root, "entry.ts"); await fsp.writeFile( @@ -282,16 +282,16 @@ describe("detailed symbol graph in native-only installs", () => { ); await fsp.writeFile(path.join(root, "dep.ts"), "export function helper() { return 1; }\n", "utf8"); - const fallbackSpies = createUnavailableJsFallbackSpies("TypeScript grammar"); + const fallbackSpies = createUnavailableParserBackendSpies("TypeScript grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: fallbackSpies.parseSpy, - executeJsQueryAsNativeMatches: fallbackSpies.querySpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: fallbackSpies.parseSpy, + executeQueryAsNativeMatches: fallbackSpies.querySpy, }; }); @@ -305,6 +305,6 @@ describe("detailed symbol graph in native-only installs", () => { snippet: "'./dep'", }), ]); - expectJsFallbackUnusedForNativeOwnership(fallbackSpies); + expectParserBackendUnusedForNativeOwnership(fallbackSpies); }); }); diff --git a/tests/esm-language-loading.test.ts b/tests/esm-language-loading.test.ts index 8f63bdaf..ab296403 100644 --- a/tests/esm-language-loading.test.ts +++ b/tests/esm-language-loading.test.ts @@ -1,14 +1,14 @@ import { describe, expect, it } from "vitest"; -import { isJsFallbackAvailable, parseWithJsLanguage } from "../src/jsFallback.js"; +import { isNonNativeParserAvailable, parseWithLanguage } from "../src/parserBackend.js"; -describe("esm fallback compatibility shim", () => { - it("imports codegraph and exposes the unavailable grammar shim", async () => { +describe("ESM parser backend unavailable contract", () => { + it("imports codegraph and exposes the unavailable parser backend", async () => { const mod = await import("../src/index.ts"); expect(mod).toBeDefined(); - expect(isJsFallbackAvailable()).toBe(false); - expect(() => parseWithJsLanguage("body { color: red; }", { name: "tree-sitter-css" })).toThrow( - "JS Tree-sitter fallback is unavailable", + expect(isNonNativeParserAvailable()).toBe(false); + expect(() => parseWithLanguage("body { color: red; }", { name: "tree-sitter-css" })).toThrow( + "Non-native Tree-sitter parser is unavailable", ); }); }); diff --git a/tests/helpers/native.ts b/tests/helpers/native.ts index 6942b02a..7dda10d2 100644 --- a/tests/helpers/native.ts +++ b/tests/helpers/native.ts @@ -11,21 +11,23 @@ export type NativeOwnershipFallbackSpies = { querySpy?: ReturnType; }; -export function createUnavailableJsFallbackSpies(grammarDescription: string): Required { +export function createUnavailableParserBackendSpies( + grammarDescription: string, +): Required { const parseSpy = vi.fn(() => { throw new Error( - `JS Tree-sitter fallback is unavailable for ${grammarDescription} loading. Install @lzehrung/codegraph-js-fallback to enable it`, + `Non-native Tree-sitter parser is unavailable for ${grammarDescription} loading; native parser is the only grammar backend`, ); }); const querySpy = vi.fn(() => { throw new Error( - "JS Tree-sitter fallback is unavailable for JS query execution. Install @lzehrung/codegraph-js-fallback to enable it", + "Non-native Tree-sitter parser is unavailable for query execution; native parser is the only grammar backend", ); }); return { parseSpy, querySpy }; } -export function expectJsFallbackUnusedForNativeOwnership(spies: NativeOwnershipFallbackSpies): void { +export function expectParserBackendUnusedForNativeOwnership(spies: NativeOwnershipFallbackSpies): void { expect(spies.parseSpy).not.toHaveBeenCalled(); if (spies.querySpy) { expect(spies.querySpy).not.toHaveBeenCalled(); diff --git a/tests/js-fallback-loader.test.ts b/tests/js-fallback-loader.test.ts deleted file mode 100644 index 6262df44..00000000 --- a/tests/js-fallback-loader.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { describe, expect, it } from "vitest"; - -import * as jsFallback from "../src/jsFallback.js"; - -describe("js fallback shim", () => { - it("always reports grammar fallback as unavailable", () => { - expect(jsFallback.isJsFallbackAvailable()).toBe(false); - expect(() => jsFallback.parseWithJsLanguage("const value = 1;", { name: "tree-sitter-javascript" })).toThrow( - "JS Tree-sitter fallback is unavailable", - ); - }); -}); diff --git a/tests/languages/sql.test.ts b/tests/languages/sql.test.ts index 2d5c6bfe..b611cb1a 100644 --- a/tests/languages/sql.test.ts +++ b/tests/languages/sql.test.ts @@ -106,24 +106,24 @@ it("includes discovered SQL files in the normal repository index", async () => { }); describe("native-only SQL support", () => { - it("indexes SQL without the JS fallback parser when native parsing is unavailable", async () => { + it("indexes SQL without a non-native parser when native parsing is unavailable", async () => { const root = await fsp.mkdtemp(path.join(os.tmpdir(), "cg-sql-native-only-")); const schemaFile = path.join(root, "schema.sql").replace(/\\/g, "/"); await fsp.writeFile(schemaFile, "CREATE TABLE users (id integer);\n", "utf8"); const parseSpy = vi.fn(() => { throw new Error( - "JS Tree-sitter fallback is unavailable for grammar loading. Install @lzehrung/codegraph-js-fallback to enable it", + "Non-native Tree-sitter parser is unavailable for grammar loading; native parser is the only grammar backend", ); }); vi.resetModules(); - vi.doMock("../../src/jsFallback.js", async () => { - const actual = await vi.importActual("../../src/jsFallback.js"); + vi.doMock("../../src/parserBackend.js", async () => { + const actual = await vi.importActual("../../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: parseSpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: parseSpy, }; }); vi.doMock("../../src/native/treeSitterNative.js", async () => { @@ -155,7 +155,7 @@ describe("native-only SQL support", () => { ); expect(parseSpy).not.toHaveBeenCalled(); } finally { - vi.doUnmock("../../src/jsFallback.js"); + vi.doUnmock("../../src/parserBackend.js"); vi.doUnmock("../../src/native/treeSitterNative.js"); vi.resetModules(); await fsp.rm(root, { recursive: true, force: true }); diff --git a/tests/native-parse-tree.test.ts b/tests/native-parse-tree.test.ts index f3a9cf45..be6a1b6d 100644 --- a/tests/native-parse-tree.test.ts +++ b/tests/native-parse-tree.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { isJsFallbackAvailable, parseWithJsLanguage } from "../src/jsFallback.js"; +import { isNonNativeParserAvailable, parseWithLanguage } from "../src/parserBackend.js"; import { TS_SUPPORT, languageForFile, supportById } from "../src/languages.js"; import { buildScopeIndexFromSource } from "../src/indexer.js"; @@ -7,7 +7,7 @@ import { getNativeSyntaxTreeExecution, isNativeTreeSitterAvailable } from "../sr import { ProjectedSyntaxTree } from "../src/native/projectedTree.js"; const nativeDescribe = isNativeTreeSitterAvailable() ? describe : describe.skip; -const jsFallbackIt = isJsFallbackAvailable() ? it : it.skip; +const nonNativeParserIt = isNonNativeParserAvailable() ? it : it.skip; nativeDescribe("native parse tree projection", () => { it("projects child and field relationships for TypeScript", () => { @@ -72,7 +72,7 @@ nativeDescribe("native parse tree projection", () => { expect(nameNode?.startIndex).toBe(unicodeSource.indexOf("afterUnicode")); }); - jsFallbackIt("builds the same TypeScript scope bindings as the JS tree walker", () => { + nonNativeParserIt("builds the same TypeScript scope bindings as the non-native tree walker", () => { const source = [ "const top = 1;", "function outer(arg: string) {", @@ -86,7 +86,7 @@ nativeDescribe("native parse tree projection", () => { const file = "scope.ts"; const lang = languageForFile(file); - const jsTree = parseWithJsLanguage(source, lang); + const jsTree = parseWithLanguage(source, lang); const nativeScope = buildScopeIndexFromSource(file, source, TS_SUPPORT, lang); const jsScope = buildScopeIndexFromSource(file, source, TS_SUPPORT, lang, [], { diff --git a/tests/native-parser-ownership.test.ts b/tests/native-parser-ownership.test.ts index 58134729..a6a84d95 100644 --- a/tests/native-parser-ownership.test.ts +++ b/tests/native-parser-ownership.test.ts @@ -1,7 +1,7 @@ import path from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; import * as nativeRuntime from "../src/native/treeSitterNative.js"; -import { createUnavailableJsFallbackSpies, expectJsFallbackUnusedForNativeOwnership } from "./helpers/native.js"; +import { createUnavailableParserBackendSpies, expectParserBackendUnusedForNativeOwnership } from "./helpers/native.js"; const nativeDescribe = nativeRuntime.isNativeTreeSitterAvailable() ? describe : describe.skip; @@ -59,20 +59,20 @@ nativeDescribe("native parser ownership", () => { afterEach(() => { vi.restoreAllMocks(); vi.resetModules(); - vi.doUnmock("../src/jsFallback.js"); + vi.doUnmock("../src/parserBackend.js"); }); - it("keeps representative source-language navigation on the native runtime when the JS fallback package is unavailable", async () => { - const fallbackSpies = createUnavailableJsFallbackSpies("grammar"); + it("keeps representative source-language navigation on the native runtime when no non-native parser is available", async () => { + const fallbackSpies = createUnavailableParserBackendSpies("grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: fallbackSpies.parseSpy, - executeJsQueryAsNativeMatches: fallbackSpies.querySpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: fallbackSpies.parseSpy, + executeQueryAsNativeMatches: fallbackSpies.querySpy, }; }); @@ -240,20 +240,20 @@ nativeDescribe("native parser ownership", () => { expect(referencesResult.status).toBe(testCase.references.expectedStatus); } - expectJsFallbackUnusedForNativeOwnership(fallbackSpies); + expectParserBackendUnusedForNativeOwnership(fallbackSpies); }, 45_000); - it("builds detailed TypeScript symbol edges without loading the JS fallback package", async () => { - const fallbackSpies = createUnavailableJsFallbackSpies("grammar"); + it("builds detailed TypeScript symbol edges without loading a non-native parser", async () => { + const fallbackSpies = createUnavailableParserBackendSpies("grammar"); vi.resetModules(); - vi.doMock("../src/jsFallback.js", async () => { - const actual = await vi.importActual("../src/jsFallback.js"); + vi.doMock("../src/parserBackend.js", async () => { + const actual = await vi.importActual("../src/parserBackend.js"); return { ...actual, - isJsFallbackAvailable: () => false, - parseWithJsLanguage: fallbackSpies.parseSpy, - executeJsQueryAsNativeMatches: fallbackSpies.querySpy, + isNonNativeParserAvailable: () => false, + parseWithLanguage: fallbackSpies.parseSpy, + executeQueryAsNativeMatches: fallbackSpies.querySpy, }; }); @@ -269,6 +269,6 @@ nativeDescribe("native parser ownership", () => { expect(detailed.nodes.size).toBeGreaterThan(0); expect(detailed.edges.length).toBeGreaterThan(0); - expectJsFallbackUnusedForNativeOwnership(fallbackSpies); + expectParserBackendUnusedForNativeOwnership(fallbackSpies); }); }); diff --git a/tests/native-query-scope.test.ts b/tests/native-query-scope.test.ts index e1c54737..ab67677a 100644 --- a/tests/native-query-scope.test.ts +++ b/tests/native-query-scope.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from "vitest"; -import { isJsFallbackAvailable } from "../src/jsFallback.js"; +import { isNonNativeParserAvailable } from "../src/parserBackend.js"; import { supportById } from "../src/languages.js"; import { collectModuleSpecifiersFromSource, type FallbackImportExtractionEvent } from "../src/graphs.js"; import { collectImportsForFile } from "../src/indexer.js"; @@ -11,10 +11,10 @@ import { type NativeQueryResults, } from "../src/native/treeSitterNative.js"; import * as nativeRuntime from "../src/native/treeSitterNative.js"; -import * as jsFallback from "../src/jsFallback.js"; +import * as parserBackend from "../src/parserBackend.js"; const nativeDescribe = isNativeTreeSitterAvailable() ? describe : describe.skip; -const jsFallbackDescribe = isJsFallbackAvailable() ? describe : describe.skip; +const nonNativeParserDescribe = isNonNativeParserAvailable() ? describe : describe.skip; afterEach(() => { vi.restoreAllMocks(); @@ -323,10 +323,10 @@ describe("authoritative empty native results", () => { ]); }); - it("uses regex recovery for TypeScript without JS fallback", () => { + it("uses regex recovery for TypeScript without non-native parser queries", () => { const support = supportById("ts")!; - const executeSpy = vi.spyOn(jsFallback, "executeJsQueryAsNativeMatches").mockImplementation(() => { - throw new Error("JS fallback should not be used for TypeScript import recovery"); + const executeSpy = vi.spyOn(parserBackend, "executeQueryAsNativeMatches").mockImplementation(() => { + throw new Error("Non-native parser should not be used for TypeScript import recovery"); }); const fallbackEvents: FallbackImportExtractionEvent[] = []; @@ -479,7 +479,7 @@ nativeDescribe("compact imports execution", () => { }); }); -jsFallbackDescribe("native import fallback contract by language", () => { +nonNativeParserDescribe("native import fallback contract by language", () => { it("treats empty native imports as authoritative for TypeScript and Java", () => { const cases = [ { diff --git a/tests/native-runtime-mode.test.ts b/tests/native-runtime-mode.test.ts index 6b4eb310..648c90e3 100644 --- a/tests/native-runtime-mode.test.ts +++ b/tests/native-runtime-mode.test.ts @@ -1,12 +1,12 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import path from "node:path"; import { buildProjectIndex, buildSymbolGraphDetailed, collectGraph, type BuildReport } from "../src/index.js"; -import { isJsFallbackAvailable } from "../src/jsFallback.js"; +import { isNonNativeParserAvailable } from "../src/parserBackend.js"; import * as nativeRuntime from "../src/native/treeSitterNative.js"; describe("native runtime mode", () => { const samplePath = path.resolve(process.cwd(), "tests", "samples", "typescript"); - const jsFallbackIt = isJsFallbackAvailable() ? it : it.skip; + const nonNativeParserIt = isNonNativeParserAvailable() ? it : it.skip; afterEach(() => { vi.restoreAllMocks(); @@ -39,7 +39,7 @@ describe("native runtime mode", () => { expect(report.backend?.native?.enabled).toBe(false); }); - jsFallbackIt("threads native: off through syntax-tree reconstruction paths", async () => { + nonNativeParserIt("threads native: off through syntax-tree reconstruction paths", async () => { const spy = vi.spyOn(nativeRuntime, "getNativeSyntaxTreeExecution"); const index = await buildProjectIndex(samplePath, { diff --git a/tests/native-tree-sitter.test.ts b/tests/native-tree-sitter.test.ts index c20208c9..72f30a70 100644 --- a/tests/native-tree-sitter.test.ts +++ b/tests/native-tree-sitter.test.ts @@ -2,7 +2,7 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterAll, describe, expect, it } from "vitest"; -import { isJsFallbackAvailable, parseWithJsLanguage } from "../src/jsFallback.js"; +import { isNonNativeParserAvailable, parseWithLanguage } from "../src/parserBackend.js"; import { collectImportsForFile, collectLocalsAndExportsFromSource, parseFile } from "../src/indexer.js"; import { languageForFile, supportForFile } from "../src/languages.js"; import { collectModuleSpecifiersFromSource } from "../src/graphs.js"; @@ -10,7 +10,7 @@ import { isNativeTreeSitterAvailable } from "../src/native/treeSitterNative.js"; import { simplifyNativeTestImports, simplifyNativeTestModuleIndex } from "./helpers/native.js"; const nativeDescribe = isNativeTreeSitterAvailable() ? describe : describe.skip; -const jsFallbackDescribe = isJsFallbackAvailable() ? describe : describe.skip; +const nonNativeParserDescribe = isNonNativeParserAvailable() ? describe : describe.skip; const sampleRoot = path.resolve(process.cwd(), "tests", "samples"); const slowNativeParityTimeoutMs = 30000; const tempDirs: string[] = []; @@ -32,7 +32,7 @@ function sampleFile(...parts: string[]): string { async function parseWithJsTreeSitter(file: string) { const parsed = await parseFile(file); const lang = languageForFile(file); - const tree = parseWithJsLanguage(parsed.source, lang); + const tree = parseWithLanguage(parsed.source, lang); return { ...parsed, tree, @@ -108,7 +108,7 @@ async function expectNativeModuleSpecifierParity(relativeFile: string): Promise< expect(nativeSpecifiers).toEqual(jsSpecifiers); } -jsFallbackDescribe("native tree-sitter integration", () => { +nonNativeParserDescribe("non-native tree-sitter integration", () => { it("matches JS import extraction with and without native query results", async () => { const projectRoot = await makeTempProject(); const entry = path.join(projectRoot, "entry.js"); diff --git a/tests/package-metadata.test.ts b/tests/package-metadata.test.ts index aa83fce1..1fa17135 100644 --- a/tests/package-metadata.test.ts +++ b/tests/package-metadata.test.ts @@ -184,25 +184,18 @@ describe("package metadata", () => { const licensePath = path.resolve(process.cwd(), "LICENSE"); const rootPackage = readJson("package.json"); const nativePackage = readJson("packages/codegraph-native/package.json"); - const fallbackPackage = readJson("packages/codegraph-js-fallback/package.json"); const nativeArtifactPackages = readNativeArtifactPackages(process.cwd()); expect(fs.existsSync(licensePath)).toBe(true); expect(fs.readFileSync(licensePath, "utf8")).toContain("MIT License"); expect(rootPackage.license).toBe("MIT"); expect(nativePackage.license).toBe("MIT"); - expect(fallbackPackage.license).toBe("MIT"); expect(nativePackage.repository).toEqual({ type: "git", url: "git+https://github.com/lzehrung/codegraph.git", directory: "packages/codegraph-native", }); - expect(fallbackPackage.repository).toEqual({ - type: "git", - url: "git+https://github.com/lzehrung/codegraph.git", - directory: "packages/codegraph-js-fallback", - }); for (const artifactPackage of nativeArtifactPackages) { expect(artifactPackage.license).toBe("MIT"); @@ -427,10 +420,8 @@ describe("package metadata", () => { it("keeps removed deprecated or redundant package edges out of manifests", () => { const rootPackage = readJson("package.json"); - const fallbackPackage = readJson("packages/codegraph-js-fallback/package.json"); const dependencies = readStringRecord(rootPackage.dependencies); const devDependencies = readStringRecord(rootPackage.devDependencies); - const fallbackDependencies = readStringRecord(fallbackPackage.dependencies); expect(dependencies["better-sqlite3"]).toBeUndefined(); expect(devDependencies["@types/better-sqlite3"]).toBeUndefined(); @@ -439,7 +430,6 @@ describe("package metadata", () => { expect(devDependencies["@typescript-eslint/parser"]).toBeUndefined(); expect(devDependencies["eslint-import-resolver-typescript"]).toBeUndefined(); expect(devDependencies["eslint-plugin-import"]).toBeUndefined(); - expect(Object.keys(fallbackDependencies)).toHaveLength(0); }); it("keeps all publishable workspaces under the packages directory", () => { @@ -452,7 +442,7 @@ describe("package metadata", () => { expect(workspaces).toEqual(["packages/*"]); }); - it("keeps JS fallback grammars out of the native package", () => { + it("keeps fallback parser exports out of the native package", () => { const nativePackage = readJson("packages/codegraph-native/package.json"); const dependencies = readStringRecord(nativePackage.dependencies); const optionalDependencies = readStringRecord(nativePackage.optionalDependencies); @@ -470,23 +460,13 @@ describe("package metadata", () => { expect(files).toEqual(["index.js", "index.d.ts", "platform.js"]); }); - it("keeps the compatibility fallback package free of grammar dependencies", () => { - const fallbackPackage = readJson("packages/codegraph-js-fallback/package.json"); - const dependencies = readStringRecord(fallbackPackage.dependencies); - - expect(dependencies["tree-sitter"]).toBeUndefined(); - expect(dependencies["tree-sitter-php"]).toBeUndefined(); - expect(dependencies["tree-sitter-typescript"]).toBeUndefined(); - expect(dependencies["tree-sitter-vue"]).toBeUndefined(); - expect(dependencies["@tree-sitter-grammars/tree-sitter-svelte"]).toBeUndefined(); - expect(dependencies["@tree-sitter-grammars/tree-sitter-zig"]).toBeUndefined(); - }); - - it("does not publish local file dependencies in the JS fallback package", () => { - const fallbackPackage = readJson("packages/codegraph-js-fallback/package.json"); - const dependencies = readStringRecord(fallbackPackage.dependencies); + it("does not keep the removed JS fallback workspace package", () => { + const rootPackage = readJson("package.json"); + const workspaces = Array.isArray(rootPackage.workspaces) ? rootPackage.workspaces : []; - expect(dependencies["@lzehrung/codegraph"]).toBeUndefined(); + expect(workspaces).toEqual(["packages/*"]); + expect(fs.existsSync(path.resolve(process.cwd(), "packages/codegraph-js-fallback"))).toBe(false); + expect(fs.existsSync(path.resolve(process.cwd(), "packages/codegraph-js-fallback/package.json"))).toBe(false); }); it("keeps the landing README linked to the canonical reference docs", () => { @@ -692,11 +672,11 @@ void onImpactItemStreaming; expect(installationDoc).toContain("@lzehrung:registry"); expect(installationDoc).toContain("reduced graph-only and regex recovery mode"); expect(installationDoc).not.toContain("--legacy-peer-deps"); - expect(skillDoc).toContain("@lzehrung/codegraph-js-fallback"); - expect(skillDoc).toContain("compatibility shim"); + expect(skillDoc).not.toContain("@lzehrung/codegraph-js-fallback"); + expect(skillDoc).not.toContain("compatibility shim"); }); - it("keeps the release workflow publishing the root, native, and fallback packages together", () => { + it("keeps the release workflow publishing only the root and native packages", () => { const workflow = readText(".github/workflows/release.yml"); const runCommands = workflowRunCommands(workflow); const buildCommand = runCommands.find((command) => command.includes("cli.js build --platform")); @@ -710,7 +690,7 @@ void onImpactItemStreaming; const createDirsIndex = workflow.indexOf("npm run native:create-npm-dirs"); const cleanupArtifactsIndex = workflow.indexOf("rm -rf native-artifacts"); const publishIndex = workflow.indexOf( - "npm run publish:${{ inputs.release_type }} -- --package root --package native --package js-fallback", + "npm run publish:${{ inputs.release_type }} -- --package root --package native", ); const releaseIndex = workflow.indexOf("Create or update GitHub Release"); const nativePackage = readJson("packages/codegraph-native/package.json"); @@ -745,7 +725,6 @@ void onImpactItemStreaming; expect(workflow).toContain('root_tag="v$root_version"'); expect(workflow).toContain('root_package_tag="@lzehrung/codegraph@$root_version"'); expect(workflow).toContain('native_tag="@lzehrung/codegraph-native@$native_version"'); - expect(workflow).toContain('fallback_tag="@lzehrung/codegraph-js-fallback@$fallback_version"'); expect(workflow).toContain( 'gh release create "$root_tag" "$tarball" --title "$root_tag" --notes-file "$release_notes"', ); @@ -761,9 +740,9 @@ void onImpactItemStreaming; expect(workflow).not.toContain("native:stage-local"); expect(publishIndex).toBeGreaterThan(cleanupArtifactsIndex); expect(releaseIndex).toBeGreaterThan(publishIndex); - expect(workflow).toContain( - "npm run publish:${{ inputs.release_type }} -- --package root --package native --package js-fallback", - ); + expect(workflow).toContain("npm run publish:${{ inputs.release_type }} -- --package root --package native"); + expect(workflow).not.toContain("js-fallback"); + expect(workflow).not.toContain("@lzehrung/codegraph-js-fallback"); }); it("keeps GitHub-owned actions off deprecated Node 20 action majors", () => { diff --git a/tests/parser-backend-unavailable.test.ts b/tests/parser-backend-unavailable.test.ts new file mode 100644 index 00000000..e55a4fd9 --- /dev/null +++ b/tests/parser-backend-unavailable.test.ts @@ -0,0 +1,12 @@ +import { describe, expect, it } from "vitest"; + +import * as parserBackend from "../src/parserBackend.js"; + +describe("parser backend unavailable contract", () => { + it("always reports non-native parsing as unavailable", () => { + expect(parserBackend.isNonNativeParserAvailable()).toBe(false); + expect(() => parserBackend.parseWithLanguage("const value = 1;", { name: "tree-sitter-javascript" })).toThrow( + "Non-native Tree-sitter parser is unavailable", + ); + }); +}); diff --git a/tests/patch-tree-sitter-node24.test.ts b/tests/patch-tree-sitter-node24.test.ts deleted file mode 100644 index 7ee594f3..00000000 --- a/tests/patch-tree-sitter-node24.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { describe, expect, it } from "vitest"; -import path from "node:path"; -import { - patchTreeSitterBindingGypSource, - resolveTreeSitterBindingGypPath, -} from "../scripts/patch-tree-sitter-node24-lib.mjs"; - -describe("tree-sitter Node 24 patcher", () => { - it("patches binding.gyp despite CRLF line endings and whitespace drift", () => { - const source = [ - "{", - ' "variables": {', - ' "v8_enable_31bit_smis_on_64bit_arch%" : 0', - " },", - ' "targets": [', - " {", - ' "cflags_cc" : [', - ' "-std=c++17",', - " ],", - ' "xcode_settings": {', - ' "CLANG_CXX_LANGUAGE_STANDARD" : "c++17"', - " },", - ' "msvs_settings": {', - ' "VCCLCompilerTool": { "AdditionalOptions": ["/std:c++17"] }', - " },", - ' "conditions": [', - " [\"OS=='linux'\", {", - ' "cflags_cc" : [', - ' "-Wno-cast-function-type"', - " ]", - " }]", - " ]", - " }", - " ]", - "}", - "", - ].join("\r\n"); - - const result = patchTreeSitterBindingGypSource(source); - - expect(result.changed).toBe(true); - expect(result.source).toContain("\r\n"); - expect(result.source).toContain('"cxxstd%": " { - const source = '{\n "variables": {\n "cxxstd%": "c++20"\n }\n}\n'; - - const result = patchTreeSitterBindingGypSource(source); - - expect(result).toEqual({ source, changed: false }); - }); - - it("resolves binding.gyp from the fallback workspace package resolution root", () => { - const repoRoot = path.resolve("repo"); - const packageJsonPath = path.join(repoRoot, "node_modules", "tree-sitter", "package.json"); - const bindingPath = path.join(path.dirname(packageJsonPath), "binding.gyp"); - - expect( - resolveTreeSitterBindingGypPath({ - repoRoot, - resolvePackageJson: () => packageJsonPath, - existsSync: (candidatePath) => candidatePath === bindingPath, - }), - ).toBe(bindingPath); - }); - - it("returns null when tree-sitter is not installed", () => { - expect( - resolveTreeSitterBindingGypPath({ - repoRoot: path.resolve("repo"), - resolvePackageJson: () => { - throw new Error("missing tree-sitter"); - }, - existsSync: () => false, - }), - ).toBeNull(); - }); -}); diff --git a/tests/release-script.test.ts b/tests/release-script.test.ts index 33db05a9..b610614c 100644 --- a/tests/release-script.test.ts +++ b/tests/release-script.test.ts @@ -22,7 +22,6 @@ import { prepareNativePackageManifestForPublish, restoreRootPackageManifest, restoreNativePackageManifest, - sanitizeJsFallbackPackageManifest, sanitizePublishedRootPackageManifest, selectLatestLegacyTag, selectLatestSemverTag, @@ -183,7 +182,7 @@ describe("release script helpers", () => { expect(isAllowedResumePath("scripts/stage-native-package.mjs")).toBe(true); expect(isAllowedResumePath("scripts/sync-native-meta.mjs")).toBe(true); expect(isAllowedResumePath("tests/release-script.test.ts")).toBe(true); - expect(isAllowedResumePath("packages/codegraph-js-fallback/package.json")).toBe(true); + expect(isAllowedResumePath("packages/codegraph-js-fallback/package.json")).toBe(false); expect(isAllowedResumePath("src/indexer.ts")).toBe(false); }); @@ -215,7 +214,7 @@ describe("release script helpers", () => { "packages/codegraph-js-fallback/package.json", "docs/scenario-catalog.md", ]), - ).toEqual(["root", "native", "js-fallback"]); + ).toEqual(["root", "native"]); }); it("treats published MCP documentation as a root package change", () => { @@ -246,19 +245,19 @@ describe("release script helpers", () => { ).toEqual(["root"]); }); - it("publishes only selected packages that are not already in the registry", () => { + it("publishes only selected root and native packages that are not already in the registry", () => { expect( computePublishPlan({ shouldPublish: true, - selectedPackageNames: ["@lzehrung/codegraph", "@lzehrung/codegraph-js-fallback"], + selectedPackageNames: ["@lzehrung/codegraph", "@lzehrung/codegraph-native"], publishedPackageNames: new Set(["@lzehrung/codegraph"]), }), ).toEqual({ publishByPackage: { "@lzehrung/codegraph": false, - "@lzehrung/codegraph-js-fallback": true, + "@lzehrung/codegraph-native": true, }, - publishNativeTargets: false, + publishNativeTargets: true, }); }); @@ -277,24 +276,16 @@ describe("release script helpers", () => { }); }); - it("publishes native and fallback packages before preparing the root manifest", () => { + it("publishes native packages before preparing the root manifest", () => { expect( computePublishExecutionSteps({ publishByPackage: { "@lzehrung/codegraph-native": true, - "@lzehrung/codegraph-js-fallback": true, "@lzehrung/codegraph": true, }, publishNativeTargets: true, }), - ).toEqual([ - "publishNativeTargets", - "prepareNativeMeta", - "publishNativeMeta", - "publishJsFallback", - "prepareRootManifest", - "publishRoot", - ]); + ).toEqual(["publishNativeTargets", "prepareNativeMeta", "publishNativeMeta", "prepareRootManifest", "publishRoot"]); }); it("selects the latest package-scoped tag by version", () => { @@ -308,9 +299,7 @@ describe("release script helpers", () => { }); it("formats package-scoped release tags", () => { - expect(tagNameForPackageVersion("@lzehrung/codegraph-js-fallback", "1.8.44")).toBe( - "@lzehrung/codegraph-js-fallback@1.8.44", - ); + expect(tagNameForPackageVersion("@lzehrung/codegraph-native", "1.8.44")).toBe("@lzehrung/codegraph-native@1.8.44"); }); it("formats both repo and package-scoped tags for root releases", () => { @@ -332,23 +321,13 @@ describe("release script helpers", () => { ]); }); - it("sanitizes the fallback package manifest for publishing", () => { - expect( - sanitizeJsFallbackPackageManifest({ - name: "@lzehrung/codegraph-js-fallback", - version: "1.8.44", - dependencies: { - "@lzehrung/codegraph": "file:../..", - "tree-sitter": "^0.25.0", - }, - }), - ).toEqual({ - name: "@lzehrung/codegraph-js-fallback", - version: "1.8.44", - dependencies: { - "tree-sitter": "^0.25.0", - }, - }); + it("rejects the removed JS fallback package selector", () => { + expect(() => getReleasePackage("js-fallback")).toThrow( + "Unknown release package selector: js-fallback. Use one of: root, @lzehrung/codegraph, native, @lzehrung/codegraph-native", + ); + expect(() => getReleasePackage("@lzehrung/codegraph-js-fallback")).toThrow( + "Unknown release package selector: @lzehrung/codegraph-js-fallback. Use one of: root, @lzehrung/codegraph, native, @lzehrung/codegraph-native", + ); }); it("sanitizes the root package manifest for publishing", () => { From 5d67465b72740c99bbb09a77bc9ad99cfb7a83fc Mon Sep 17 00:00:00 2001 From: Luke Zehrung Date: Sat, 20 Jun 2026 13:15:28 -0400 Subject: [PATCH 2/3] Address parser backend review comments --- src/indexer/imports/nativeCaptures.ts | 75 +-------------------------- src/parserBackend.ts | 8 +-- 2 files changed, 6 insertions(+), 77 deletions(-) diff --git a/src/indexer/imports/nativeCaptures.ts b/src/indexer/imports/nativeCaptures.ts index fad8b7c8..a28de70f 100644 --- a/src/indexer/imports/nativeCaptures.ts +++ b/src/indexer/imports/nativeCaptures.ts @@ -1,7 +1,6 @@ -import type { ParserSyntaxTree } from "../../parserBackend.js"; -import { capturesByName, capturesNamed, rangeFromNativeCapture } from "../../native/queryResults.js"; +import { capturesByName, capturesNamed } from "../../native/queryResults.js"; import type { NativeCapture, NativeMatch } from "../../native/treeSitterNative.js"; -import { sliceText, unquote } from "../../util/ast.js"; +import { unquote } from "../../util/ast.js"; import { utf8ByteOffsetToStringIndex } from "../../util/rustTestModules.js"; import { parseGoImportAlias } from "../shared.js"; import type { ImportBinding } from "../types.js"; @@ -62,52 +61,6 @@ async function pushTextObjectPatternBindings( } } -async function pushTreeObjectPatternBindings( - context: ImportCaptureExtractionContext, - tree: ParserSyntaxTree, - patterns: NativeCapture[], - from: string | undefined, - typeOnly: boolean, -): Promise { - if (!from) return; - for (const pattern of patterns) { - const patternRange = rangeFromNativeCapture(pattern); - const patternNode = tree.rootNode.descendantForIndex(patternRange.start.index ?? 0, patternRange.end.index ?? 0); - if (patternNode.type !== "object_pattern") continue; - - for (const child of patternNode.namedChildren) { - if (child.type === "shorthand_property_identifier" || child.type === "shorthand_property_identifier_pattern") { - const name = sliceText(child, context.source); - const resolved = await context.resolveFrom(from); - context.pushBinding({ - kind: "named", - local: name, - imported: name, - from, - resolved, - typeOnly, - }); - } else if (child.type === "pair_pattern") { - const key = child.childForFieldName("key"); - const value = child.childForFieldName("value"); - if (key && value && key.type === "property_identifier" && value.type === "identifier") { - const imported = sliceText(key, context.source); - const local = sliceText(value, context.source); - const resolved = await context.resolveFrom(from); - context.pushBinding({ - kind: "named", - local, - imported, - from, - resolved, - typeOnly, - }); - } - } - } - } -} - function pushNamespaceBinding( context: ImportCaptureExtractionContext, caps: Record, @@ -221,27 +174,3 @@ export async function collectNativeCaptureImportBindings( await pushStandardBindings(context, match, caps, stmtText, from, patterns.length, typeOnly); } } - -export async function collectJsQueryCaptureImportBindings( - context: ImportCaptureExtractionContext, - matches: NativeMatch[], - tree: ParserSyntaxTree, -): Promise { - for (const match of matches) { - const caps = capturesByName(match); - const statementCapture = caps["stmt"]; - const stmtText = statementCapture?.text ?? ""; - const typeOnly = context.isTypeOnly(stmtText); - const statementStartIndex = - statementCapture !== undefined - ? utf8ByteOffsetToStringIndex(context.source, statementCapture.start.index) - : undefined; - if (await context.applyStatementOverride(stmtText, typeOnly, statementStartIndex)) { - continue; - } - const from = caps["from"] ? unquote(caps["from"].text) : undefined; - const patterns = capturesNamed(match, "pattern"); - await pushTreeObjectPatternBindings(context, tree, patterns, from, typeOnly); - await pushStandardBindings(context, match, caps, stmtText, from, patterns.length, typeOnly); - } -} diff --git a/src/parserBackend.ts b/src/parserBackend.ts index 7eacba74..7d3aa888 100644 --- a/src/parserBackend.ts +++ b/src/parserBackend.ts @@ -50,11 +50,11 @@ export interface QueryMatch { captures: QueryCapture[]; } -const NON_NATIVE_PARSER_UNAVAILABLE_MESSAGE = - "Non-native Tree-sitter parser is unavailable; native parser is the only grammar backend"; +const NON_NATIVE_PARSER_UNAVAILABLE_PREFIX = "Non-native Tree-sitter parser is unavailable"; +const NON_NATIVE_PARSER_UNAVAILABLE_SUFFIX = "native parser is the only grammar backend"; function createUnavailableError(feature: string): Error { - return new Error(`${NON_NATIVE_PARSER_UNAVAILABLE_MESSAGE} for ${feature}`); + return new Error(`${NON_NATIVE_PARSER_UNAVAILABLE_PREFIX} for ${feature}; ${NON_NATIVE_PARSER_UNAVAILABLE_SUFFIX}`); } export function __resetParserBackendModuleForTests(): void { @@ -66,7 +66,7 @@ export function isNonNativeParserAvailable(): boolean { } export function isNonNativeParserUnavailableError(error: unknown): boolean { - return error instanceof Error && error.message.includes(NON_NATIVE_PARSER_UNAVAILABLE_MESSAGE); + return error instanceof Error && error.message.includes(NON_NATIVE_PARSER_UNAVAILABLE_PREFIX); } export function loadTreeSitterLanguage(packageName: string): ParserLanguage { From b43b6df0325bcc78071d3a6570cf83cfd60388c6 Mon Sep 17 00:00:00 2001 From: Luke Zehrung Date: Sat, 20 Jun 2026 13:30:38 -0400 Subject: [PATCH 3/3] Clarify non-native parser test names --- tests/native-parse-tree.test.ts | 8 +-- tests/native-tree-sitter.test.ts | 95 +++++++++++++++++++------------- 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/tests/native-parse-tree.test.ts b/tests/native-parse-tree.test.ts index be6a1b6d..a96969c0 100644 --- a/tests/native-parse-tree.test.ts +++ b/tests/native-parse-tree.test.ts @@ -86,11 +86,11 @@ nativeDescribe("native parse tree projection", () => { const file = "scope.ts"; const lang = languageForFile(file); - const jsTree = parseWithLanguage(source, lang); + const tree = parseWithLanguage(source, lang); const nativeScope = buildScopeIndexFromSource(file, source, TS_SUPPORT, lang); - const jsScope = buildScopeIndexFromSource(file, source, TS_SUPPORT, lang, [], { - tree: jsTree, + const nonNativeScope = buildScopeIndexFromSource(file, source, TS_SUPPORT, lang, [], { + tree, }); const normalize = (scopeIndex: ReturnType) => @@ -107,6 +107,6 @@ nativeDescribe("native parse tree projection", () => { })) .sort((left, right) => left.name.localeCompare(right.name)); - expect(normalize(nativeScope)).toEqual(normalize(jsScope)); + expect(normalize(nativeScope)).toEqual(normalize(nonNativeScope)); }); }); diff --git a/tests/native-tree-sitter.test.ts b/tests/native-tree-sitter.test.ts index 72f30a70..17bc3c90 100644 --- a/tests/native-tree-sitter.test.ts +++ b/tests/native-tree-sitter.test.ts @@ -29,7 +29,7 @@ function sampleFile(...parts: string[]): string { return path.join(sampleRoot, ...parts); } -async function parseWithJsTreeSitter(file: string) { +async function parseWithNonNativeParser(file: string) { const parsed = await parseFile(file); const lang = languageForFile(file); const tree = parseWithLanguage(parsed.source, lang); @@ -44,7 +44,7 @@ async function expectNativeImportParity(projectDir: string, relativeFile: string const projectRoot = sampleFile(projectDir); const file = path.join(projectRoot, relativeFile); const nativeParsed = await parseFile(file); - const jsParsed = await parseWithJsTreeSitter(file); + const nonNativeParsed = await parseWithNonNativeParser(file); expect(nativeParsed.nativeQueries).not.toBeNull(); const nativeImports = await collectImportsForFile(file, projectRoot, { @@ -53,21 +53,21 @@ async function expectNativeImportParity(projectDir: string, relativeFile: string lang: nativeParsed.lang, nativeQueries: nativeParsed.nativeQueries, }); - const jsImports = await collectImportsForFile(file, projectRoot, { - source: jsParsed.source, - tree: jsParsed.tree, - sup: jsParsed.sup, - lang: jsParsed.lang, + const nonNativeImports = await collectImportsForFile(file, projectRoot, { + source: nonNativeParsed.source, + tree: nonNativeParsed.tree, + sup: nonNativeParsed.sup, + lang: nonNativeParsed.lang, nativeMode: "off", }); - expect(simplifyNativeTestImports(nativeImports)).toEqual(simplifyNativeTestImports(jsImports)); + expect(simplifyNativeTestImports(nativeImports)).toEqual(simplifyNativeTestImports(nonNativeImports)); } async function expectNativeModuleIndexParity(relativeFile: string): Promise { const file = sampleFile(relativeFile); const nativeParsed = await parseFile(file); - const jsParsed = await parseWithJsTreeSitter(file); + const nonNativeParsed = await parseWithNonNativeParser(file); expect(nativeParsed.nativeQueries).not.toBeNull(); const nativeIndex = collectLocalsAndExportsFromSource( @@ -81,12 +81,19 @@ async function expectNativeModuleIndexParity(relativeFile: string): Promise { @@ -99,13 +106,13 @@ async function expectNativeModuleSpecifierParity(relativeFile: string): Promise< nativeQueries: parsed.nativeQueries, file, }); - const jsSpecifiers = collectModuleSpecifiersFromSource(parsed.sup, parsed.lang, parsed.source, { + const reducedModeSpecifiers = collectModuleSpecifiersFromSource(parsed.sup, parsed.lang, parsed.source, { tree: parsed.tree, file, native: "off", }); - expect(nativeSpecifiers).toEqual(jsSpecifiers); + expect(nativeSpecifiers).toEqual(reducedModeSpecifiers); } nonNativeParserDescribe("non-native tree-sitter integration", () => { @@ -127,7 +134,7 @@ nonNativeParserDescribe("non-native tree-sitter integration", () => { await fs.writeFile(path.join(projectRoot, "cjs-default.js"), "module.exports = () => 1;\n"); const nativeParsed = await parseFile(entry); - const jsParsed = await parseWithJsTreeSitter(entry); + const nonNativeParsed = await parseWithNonNativeParser(entry); expect(nativeParsed.nativeQueries).not.toBeNull(); const nativeImports = await collectImportsForFile(entry, projectRoot, { @@ -136,15 +143,15 @@ nonNativeParserDescribe("non-native tree-sitter integration", () => { lang: nativeParsed.lang, nativeQueries: nativeParsed.nativeQueries, }); - const jsImports = await collectImportsForFile(entry, projectRoot, { - source: jsParsed.source, - tree: jsParsed.tree, - sup: jsParsed.sup, - lang: jsParsed.lang, + const nonNativeImports = await collectImportsForFile(entry, projectRoot, { + source: nonNativeParsed.source, + tree: nonNativeParsed.tree, + sup: nonNativeParsed.sup, + lang: nonNativeParsed.lang, nativeMode: "off", }); - expect(simplifyNativeTestImports(nativeImports)).toEqual(simplifyNativeTestImports(jsImports)); + expect(simplifyNativeTestImports(nativeImports)).toEqual(simplifyNativeTestImports(nonNativeImports)); }); it("matches Python locals and exports with and without native query results", async () => { @@ -168,7 +175,7 @@ nonNativeParserDescribe("non-native tree-sitter integration", () => { ); const nativeParsed = await parseFile(file); - const jsParsed = await parseWithJsTreeSitter(file); + const nonNativeParsed = await parseWithNonNativeParser(file); expect(nativeParsed.nativeQueries).not.toBeNull(); const nativeIndex = collectLocalsAndExportsFromSource( @@ -182,12 +189,19 @@ nonNativeParserDescribe("non-native tree-sitter integration", () => { nativeQueries: nativeParsed.nativeQueries, }, ); - const jsIndex = collectLocalsAndExportsFromSource(file, jsParsed.source, jsParsed.sup, jsParsed.lang, [], { - tree: jsParsed.tree, - nativeMode: "off", - }); + const nonNativeIndex = collectLocalsAndExportsFromSource( + file, + nonNativeParsed.source, + nonNativeParsed.sup, + nonNativeParsed.lang, + [], + { + tree: nonNativeParsed.tree, + nativeMode: "off", + }, + ); - expect(simplifyNativeTestModuleIndex(nativeIndex)).toEqual(simplifyNativeTestModuleIndex(jsIndex)); + expect(simplifyNativeTestModuleIndex(nativeIndex)).toEqual(simplifyNativeTestModuleIndex(nonNativeIndex)); }); it("matches HTML module specifier extraction with and without native query results", async () => { @@ -212,13 +226,13 @@ nonNativeParserDescribe("non-native tree-sitter integration", () => { nativeQueries: parsed.nativeQueries, file, }); - const jsSpecifiers = collectModuleSpecifiersFromSource(parsed.sup, parsed.lang, source, { + const reducedModeSpecifiers = collectModuleSpecifiersFromSource(parsed.sup, parsed.lang, source, { tree: parsed.tree, file, native: "off", }); - expect(nativeSpecifiers).toEqual(jsSpecifiers); + expect(nativeSpecifiers).toEqual(reducedModeSpecifiers); }); it("matches TypeScript export extraction for export assignment and classes", async () => { @@ -235,7 +249,7 @@ nonNativeParserDescribe("non-native tree-sitter integration", () => { ); const nativeParsed = await parseFile(file); - const jsParsed = await parseWithJsTreeSitter(file); + const nonNativeParsed = await parseWithNonNativeParser(file); expect(nativeParsed.nativeQueries).not.toBeNull(); const nativeIndex = collectLocalsAndExportsFromSource( @@ -249,12 +263,19 @@ nonNativeParserDescribe("non-native tree-sitter integration", () => { nativeQueries: nativeParsed.nativeQueries, }, ); - const jsIndex = collectLocalsAndExportsFromSource(file, jsParsed.source, jsParsed.sup, jsParsed.lang, [], { - tree: jsParsed.tree, - nativeMode: "off", - }); + const nonNativeIndex = collectLocalsAndExportsFromSource( + file, + nonNativeParsed.source, + nonNativeParsed.sup, + nonNativeParsed.lang, + [], + { + tree: nonNativeParsed.tree, + nativeMode: "off", + }, + ); - expect(simplifyNativeTestModuleIndex(nativeIndex)).toEqual(simplifyNativeTestModuleIndex(jsIndex)); + expect(simplifyNativeTestModuleIndex(nativeIndex)).toEqual(simplifyNativeTestModuleIndex(nonNativeIndex)); }); it(