# What Languages Are Supported in code-review-graph and How the Tree-sitter Parser Handles Them

> Explore the 25+ programming languages supported by code-review-graph. Learn how the Tree-sitter parser efficiently handles grammars using subprocess probing and cache checks for seamless code analysis.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: internals
- Published: 2026-07-30

---

**The code-review-graph library supports over 25 programming languages out of the box through Tree-sitter grammars provided by tree-sitter-language-pack, implementing lazy grammar loading with subprocess probing, cache-based availability checks, and regex-based fallbacks for unsupported languages.**

The `tirth8205/code-review-graph` repository extracts structural code elements—such as classes, functions, and imports—to build dependency graphs. It relies on the Tree-sitter parsing engine via the `tree-sitter-language-pack` distribution to handle language-specific syntax across its supported language set.

## Built-in Language Coverage

The core language detection resides in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py), where an extension-to-language table (lines 83–107) maps file extensions to Tree-sitter grammar identifiers. The table currently includes:

- **Python** (`.py`)
- **JavaScript** (`.js`, `.jsx`, `.mjs`)
- **TypeScript / TSX** (`.ts`, `.tsx`, `.astro`)
- **Go** (`.go`)
- **Rust** (`.rs`)
- **Java** (`.java`)
- **C#** (`.cs`)
- **Ruby** (`.rb`)
- **C / C++** (`.c`, `.h`, `.cpp`, `.cc`, `.cxx`, `.hpp`, `.hh`)
- **Kotlin** (`.kt`)
- **Swift** (`.swift`)
- **PHP** (`.php`)
- **Scala** (`.scala`)
- **Solidity** (`.sol`)
- **Vue** (`.vue`)
- **Dart** (`.dart`)
- **R** (`.r`, `.R`)
- **Lua / Luau** (`.lua`, `.luau`)
- **Objective-C** (`.m`)
- **Bash / Zsh / Ksh** (`.sh`, `.bash`, `.zsh`, `.ksh`)
- **Elixir** (`.ex`, `.exs`)
- **Perl** (`.pl`, `.pm`, `.t`)
- **Zig** (`.zig`)
- **PowerShell** (`.ps1`, `.psm1`, `.psd1`)
- **Svelte** (`.svelte`)
- **Julia** (`.jl`)
- **Verilog / SystemVerilog** (`.v`, `.vh`, `.sv`, `.svh`)

For each language, the parser maintains node-type mappings (lines 837–1070) such as `_CLASS_TYPES`, `_FUNCTION_TYPES`, `_IMPORT_TYPES`, and `_CALL_TYPES`, which tell the generic walker which Tree-sitter nodes represent structural elements.

## Lazy Grammar Loading and Probe Caching

When a file requires parsing, the engine attempts to load the corresponding Tree-sitter grammar lazily. The `_load_tree_sitter_parser` function in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py) handles this by importing `tree_sitter_language_pack` and calling `get_parser(grammar)`:

```python
def _load_tree_sitter_parser(grammar: str):
    if not _parser_load_probe_succeeds(grammar):
        return None
    language_pack = importlib.import_module("tree_sitter_language_pack")
    return language_pack.get_parser(grammar)

```

The helper `_parser_load_probe_succeeds` (lines 510–545) spawns a short-lived subprocess to test if the grammar is available. If loading fails, the result is cached to prevent repeated subprocess overhead, and the parser returns `None`.

## Fallback Heuristics for Unsupported Grammars

When a Tree-sitter grammar is unavailable, the system falls back to language-specific heuristics or regex-based extraction. This covers languages like VB.NET, ReScript, SQL, and HCL that may not be present in the language pack. These fallback implementations reside in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py) alongside the primary Tree-sitter logic, as documented in [`docs/CUSTOM_LANGUAGES.md`](https://github.com/tirth8205/code-review-graph/blob/main/docs/CUSTOM_LANGUAGES.md).

## Custom Language Configuration

Users can extend support without modifying the library code by providing a [`.code-review-graph/languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/.code-review-graph/languages.toml) file. The [`custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/custom_languages.py) module (lines 1–35) reads this configuration, validates that the grammar exists in `tree-sitter-language-pack`, and merges the custom extension mappings into the core tables.

For example, to add Erlang support:

```toml
[[language]]
extension = ".erl"
grammar = "erlang"
class_node_types = ["attribute", "record"]
function_node_types = ["function"]
import_node_types = ["include"]
call_node_types = ["call"]

```

Load the configuration at runtime:

```python
from code_review_graph.custom_languages import load_custom_languages
load_custom_languages(Path(".code-review-graph/languages.toml"))

```

## Generic Syntax Tree Walking

Once a `tree_sitter.Parser` is obtained, the generic walker executes the following steps:

1. **Identify language** from file extension or shebang (see `SHEBANG_INTERPRETER_TO_LANGUAGE` in lines 560–684)
2. **Select node-type lists** (`_CLASS_TYPES`, `_FUNCTION_TYPES`, etc.) for the identified language
3. **Traverse the tree**, collecting nodes whose `type` appears in the selected lists, recording `NodeInfo` and `EdgeInfo` objects (defined around line 650)
4. **Apply static dead-guard detection** (lines 888–938) to ignore calls inside `if false` or `#if 0` blocks for non-Python languages

This generic approach ensures that new grammars require only node-type mappings without changes to the core parsing logic.

## Practical Code Examples

### Parsing a Python File

To process a built-in language like Python:

```python
from code_review_graph.parser import CodeReviewGraphParser
parser = CodeReviewGraphParser()
nodes, edges = parser.parse_file(Path("my_project/main.py"))
print(f"Found {len(nodes)} nodes, {len(edges)} edges")

```

### Handling Missing Grammars

If a file extension is not recognized or the grammar is unavailable, the parser returns empty collections and logs a warning:

```python
from code_review_graph.parser import CodeReviewGraphParser
parser = CodeReviewGraphParser()

# Suppose ".xyz" is not shipped in tree_sitter_language_pack

nodes, edges = parser.parse_file(Path("unknown.xyz"))

# Returns empty nodes/edges with warning: "Skipping unavailable tree-sitter parser for xyz"

```

## Summary

- **code-review-graph** supports 25+ languages via `tree-sitter-language-pack` grammars defined in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py) (lines 83–107)
- The **Tree-sitter parser** loads grammars lazily using `_load_tree_sitter_parser` with subprocess probing (`_parser_load_probe_succeeds`, lines 508–545) and caches availability results to avoid overhead
- **Node-type mappings** (`_CLASS_TYPES`, `_FUNCTION_TYPES`, etc., lines 837–1070) drive the generic syntax tree walker
- **Fallback parsers** handle unsupported languages when Tree-sitter grammars are unavailable
- **Custom languages** are supported via [`.code-review-graph/languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/.code-review-graph/languages.toml) processed by [`custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/custom_languages.py) without code changes
- **Shebang detection** (lines 560–684) and **dead-guard analysis** (lines 888–938) provide robust edge-case handling

## Frequently Asked Questions

### How does code-review-graph handle files without extensions?

The parser examines shebang lines (e.g., `#!/usr/bin/env python3`) using the `SHEBANG_INTERPRETER_TO_LANGUAGE` mapping (lines 560–684 in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py)) to determine the language when file extensions are absent.

### Can I add support for a language not listed in the built-in table?

Yes. Create a [`.code-review-graph/languages.toml`](https://github.com/tirth8205/code-review-graph/blob/main/.code-review-graph/languages.toml) file specifying the grammar name (must exist in `tree-sitter-language-pack`) and node types, then call `load_custom_languages()` from [`code_review_graph/custom_languages.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/custom_languages.py). No source code modifications are required.

### What happens if tree-sitter-language-pack doesn't include a grammar I need?

The system marks the grammar as unavailable via the probe cache (lines 508–545) and falls back to regex-based extraction or language-specific heuristics defined in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py), or skips the file with a warning if no fallback exists.

### How does the parser optimize performance for missing grammars?

The `_parser_load_probe_succeeds` function caches failed probe results to ensure that unavailable grammars are not retried within the same process, eliminating repeated subprocess overhead during batch operations.