# Contributing to mir

Thank you for taking the time to contribute!

## Prerequisites

- Rust (stable, 1.75+)
- PHP is **not** required — stubs are embedded at compile time

## Getting the source

```bash
git clone --recurse-submodules https://github.com/jorgsowa/mir.git
cd mir
```

The `--recurse-submodules` flag initialises the
[phpstorm-stubs](https://github.com/JetBrains/phpstorm-stubs) submodule at
`crates/mir-analyzer/phpstorm-stubs`. The build succeeds without it but PHP
built-in functions, classes, and constants will not be recognised.

If you already cloned without the flag:

```bash
git submodule update --init
```

## Building

```bash
cargo build
```

## Running tests

```bash
cargo test
```

Tests include:
- Unit tests inline in each crate
- Fixture-based integration tests in `crates/mir-analyzer/tests/fixtures/`
  (auto-generated by `build.rs` from `.phpt` files)

### Writing a fixture test

Fixture files live under `crates/mir-analyzer/tests/fixtures/<category>/`.
Each file is a `.phpt` that contains PHP source followed by expected issues:

```
===source===
<?php

function foo(): int {
    return "oops";
}
===expect===
InvalidReturnType: function foo expects return type int, string provided
```

The `===expect===` section lists expected issues, one per line. Each line is
formatted as `IssueKind: message`. The test passes when the analyzer emits
exactly those issues. An empty `===expect===` section asserts the snippet is clean.

Run only the fixture tests:

```bash
cargo test -p mir-analyzer
```

## Built-in stubs

PHP built-ins are provided in two layers:

1. **phpstorm-stubs** (authoritative) — the git submodule at
   `crates/mir-analyzer/phpstorm-stubs`. At compile time, `build.rs` embeds
   selected `.php` files via `include_str!()`. To add coverage for a new PHP
   extension, add its directory name to `STUB_DIRS` in `build.rs`.

2. **Hand-written supplements** — `crates/mir-analyzer/src/stubs.rs`. Use
   these only when phpstorm-stubs lacks the required precision (e.g.
   by-reference variadic parameters, PHPUnit helpers).

To update phpstorm-stubs to the latest upstream:

```bash
git submodule update --remote crates/mir-analyzer/phpstorm-stubs
git add crates/mir-analyzer/phpstorm-stubs
git commit -m "chore(stubs): update phpstorm-stubs to latest"
```

## Code style

```bash
cargo fmt --all
cargo clippy --all-targets -- -D warnings
```

CI enforces both; please run them locally before pushing.

## Pull requests

- Target the `main` branch.
- Include a short description of the motivation and a test (fixture or unit).
- Keep commits focused; squash fixups before opening the PR.
- Reference any related issue with `Fixes #<number>` or `Closes #<number>`.
