# How code-review-graph Resolves Cross-Language Dependencies and Imports

> Discover how code-review-graph resolves cross-language dependencies by normalizing imports and matching symbols via its graph database. Understand complex codebases easily.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: how-to-guide
- Published: 2026-08-06

---

**The code-review-graph system resolves cross-language dependencies by normalizing import statements through language-specific tokenization and querying a SQLite-backed graph database to match symbols across language boundaries.**

The open-source tool **code-review-graph** (available at `tirth8205/code-review-graph`) constructs a unified dependency graph across heterogeneous codebases. Understanding how it handles **cross-language dependencies and imports** requires examining the scoped resolution engine that maps imports from one language to concrete symbols in another while maintaining strict language boundaries.

## Language-Agnostic Import Resolution

The core resolution logic lives in [`code_review_graph/scoped_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/scoped_resolver.py). This module implements a multi-phase pipeline that transforms raw import statements into resolvable graph queries.

### Token Normalization with `_fold`

The resolver first splits import targets into path segments using language-specific separators. The **`_fold`** helper function normalizes tokens by applying case-folding rules appropriate to each language—lower-casing segments for case-insensitive languages like PHP while preserving case for Rust or C#. Normalization uses separators such as `.` (Python), `\` (PHP), and `/` (JavaScript/TypeScript) to break import paths into comparable token sequences.

### Safe Suffix Validation

Before querying the database, the resolver validates imports against **`_safe_import_suffixes`** to eliminate ambiguous partial matches. Each language maintains distinct rules: **Rust** requires at least two path segments, **PHP** treats the entire path case-insensitively, and **C#** follows namespace conventions. This whitelist ensures that `import foo` in Python does not spuriously match a Rust module named `foo` when insufficient context exists.

### SQLite Graph Queries

The resolver loads language metadata by executing `SELECT DISTINCT file_path, language FROM nodes` against the SQLite graph database. It constructs a **method map** keyed by the tuple `(language, class_key, method_key)`, then queries the `nodes` table for candidates where `qualified_name` and `language` match the normalized import tokens.

## Cross-Language Matching Strategy

Cross-language resolution relies on composite keys that include the source language identifier. Because the method map is **keyed by language**, a PHP class named `User` never resolves to a Rust type named `User`. The resolver performs final candidate filtering by comparing folded token sequences:

```python
_fold(left, language) == _fold(right, language)

```

When multiple candidates survive filtering, the resolver applies a language-matching preference hierarchy, selecting the candidate whose file language matches the import statement's source language before falling back to best-effort suffix matching.

## Key Source Files and Architecture

| File | Purpose |
|------|---------|
| [`code_review_graph/scoped_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/scoped_resolver.py) | Core resolution engine implementing `_fold`, suffix validation, and database lookups. |
| [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py) | Populates the graph with `IMPORTS_FROM` edges using tree-sitter parsers. |
| [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py) | Wraps the SQLite database, exposing the `nodes` table and edge creation methods. |
| [`code_review_graph/python_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/python_resolver.py) | Supplies Python-specific import resolution hints to the scoped resolver. |
| [`code_review_graph/tsconfig_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/tsconfig_resolver.py) | Handles TypeScript path aliasing by parsing [`tsconfig.json`](https://github.com/tirth8205/code-review-graph/blob/main/tsconfig.json) mappings. |

## Practical Resolution Examples

The following example demonstrates parsing a mixed-language project and querying cross-language import edges:

```python
from code_review_graph.parser import CodeParser
from code_review_graph.graph import GraphStore

# Initialize the parser and graph store

parser = CodeParser()
graph = GraphStore()

# Parse a directory containing Python, JavaScript, and PHP files

parser.parse_path("/path/to/project", graph)

# Retrieve cross-language import edges from a Python file

python_file = "/path/to/project/app/main.py"
imports = graph.edges_from(python_file, kind="IMPORTS_FROM")

for edge in imports:
    print(f"{edge.source} -> {edge.target} ({edge.language})")

```

Alternatively, invoke the resolution pipeline via CLI:

```bash
python -m code_review_graph.main /path/to/project --resolve-imports

```

## Summary

- **Normalization pipeline**: The `_fold` function in [`scoped_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/scoped_resolver.py) tokenizes imports using language-specific separators and case rules.
- **Language isolation**: Composite keys `(language, class_key, method_key)` prevent cross-language symbol collision.
- **Database integration**: Resolution queries the SQLite `nodes` table for `qualified_name` and `language` matches.
- **Multi-language support**: Specialized resolvers for Python, TypeScript, PHP, Rust, and C# feed language-specific rules into the generic engine.

## Frequently Asked Questions

### How does code-review-graph prevent false matches between languages with similar naming conventions?

The system isolates symbols by including the **source language** as a primary key component in the method map. When comparing candidates, the resolver executes `_fold(left, language) == _fold(right, language)`, ensuring that case-folding and tokenization rules apply within a single language context, preventing a PHP class from resolving to a Rust struct of the same name.

### Which database table stores the language metadata for import resolution?

The **`nodes`** table stores language metadata in the `language` column alongside `file_path` and `qualified_name`. The resolver queries this table with `SELECT DISTINCT file_path, language FROM nodes` to build the initial language index before resolving import paths.

### What languages receive special handling in the safe suffix validation logic?

**Rust**, **C#**, and **PHP** receive explicit handling in the `_safe_import_suffixes` logic. Rust imports must contain at least two segments, PHP paths undergo case-insensitive normalization, and C# follows namespace-specific validation rules to ensure valid cross-references.

### Can the resolver handle TypeScript path aliases defined in tsconfig.json?

Yes. The **[`code_review_graph/tsconfig_resolver.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/tsconfig_resolver.py)** module parses [`tsconfig.json`](https://github.com/tirth8205/code-review-graph/blob/main/tsconfig.json) files to extract path mappings and base URL configurations. These mappings feed into the scoped resolver, allowing imports like `import { foo } from '@/utils'` to resolve correctly to their physical file locations across language boundaries.