|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance for AI agents working on the phpstan-beberlei-assert repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is a PHPStan extension that provides type narrowing support for the [beberlei/assert](https://github.com/beberlei/assert) library. When users call assertion methods like `Assertion::integer($a)`, PHPStan normally doesn't understand that `$a` is guaranteed to be an integer after that call. This extension teaches PHPStan to narrow types after beberlei/assert assertions, improving static analysis accuracy. |
| 8 | + |
| 9 | +## PHP Version Support |
| 10 | + |
| 11 | +This repository supports **PHP 7.4+**. The `composer.json` has `"php": "^7.4 || ^8.0"` and the platform is pinned to `7.4.6`. Do not use PHP 8.0+ syntax (named arguments, match expressions, union types in signatures, etc.). |
| 12 | + |
| 13 | +## Build Commands |
| 14 | + |
| 15 | +All commands are defined in the `Makefile`: |
| 16 | + |
| 17 | +- `make check` — runs all checks (lint, cs, tests, phpstan) |
| 18 | +- `make tests` — runs PHPUnit tests (`vendor/bin/phpunit`) |
| 19 | +- `make lint` — runs parallel-lint on `src/` and `tests/` |
| 20 | +- `make cs` — runs coding standard checks (requires `make cs-install` first to clone `phpstan/build-cs`) |
| 21 | +- `make cs-fix` — auto-fixes coding standard violations |
| 22 | +- `make phpstan` — runs PHPStan at level 8 on `src/` and `tests/` |
| 23 | +- `make phpstan-generate-baseline` — regenerates the PHPStan baseline file |
| 24 | + |
| 25 | +### Running Checks Locally |
| 26 | + |
| 27 | +```bash |
| 28 | +composer install |
| 29 | +make tests # fast feedback loop |
| 30 | +make phpstan # static analysis |
| 31 | +make check # full CI-equivalent check (requires cs-install first) |
| 32 | +``` |
| 33 | + |
| 34 | +## Repository Structure |
| 35 | + |
| 36 | +``` |
| 37 | +src/Type/BeberleiAssert/ — Extension source code |
| 38 | +tests/Type/BeberleiAssert/ — Tests |
| 39 | +tests/Type/BeberleiAssert/data/ — PHP test fixture files |
| 40 | +extension.neon — PHPStan service definitions (entry point for users) |
| 41 | +phpstan.neon — PHPStan configuration for analysing this project itself |
| 42 | +phpstan-baseline.neon — PHPStan baseline for known issues |
| 43 | +``` |
| 44 | + |
| 45 | +## Architecture |
| 46 | + |
| 47 | +The extension registers five services in `extension.neon`: |
| 48 | + |
| 49 | +1. **AssertTypeSpecifyingExtension** — Handles static method calls on `Assert\Assertion` (e.g., `Assertion::integer()`, `Assertion::nullOrString()`, `Assertion::allNotNull()`). Implements `StaticMethodTypeSpecifyingExtension`. |
| 50 | + |
| 51 | +2. **AssertionChainTypeSpecifyingExtension** — Handles fluent assertion chain method calls on `Assert\AssertionChain` (e.g., `Assert::that($x)->string()`). Implements `MethodTypeSpecifyingExtension`. |
| 52 | + |
| 53 | +3. **AssertionChainDynamicReturnTypeExtension** — Returns custom types (`AssertThatType`, `AssertThatAllType`, `AssertThatNullOrType`) from chain method calls like `->all()` and `->nullOr()`. Implements `DynamicMethodReturnTypeExtension`. |
| 54 | + |
| 55 | +4. **AssertThatDynamicMethodReturnTypeExtension** — Handles `Assert::that()`, `Assert::thatNullOr()`, `Assert::thatAll()` static calls. Implements `DynamicStaticMethodReturnTypeExtension`. |
| 56 | + |
| 57 | +5. **AssertThatFunctionDynamicReturnTypeExtension** — Handles `Assert\that()`, `Assert\thatNullOr()`, `Assert\thatAll()` function calls. Implements `DynamicFunctionReturnTypeExtension`. |
| 58 | + |
| 59 | +**AssertHelper** is the core class that maps assertion method names (e.g., `integer`, `string`, `notNull`, `isInstanceOf`) to equivalent PHP expressions that PHPStan's type specifier can understand. For example, `Assertion::integer($a)` is translated to the expression `is_int($a)`. |
| 60 | + |
| 61 | +The three custom type classes (`AssertThatType`, `AssertThatAllType`, `AssertThatNullOrType`) extend `ObjectType` and carry the original expression being asserted, enabling the chain-style API to narrow types. |
| 62 | + |
| 63 | +## Testing Patterns |
| 64 | + |
| 65 | +Tests use PHPStan's built-in testing infrastructure: |
| 66 | + |
| 67 | +- **Type inference tests** (`AssertTypeSpecifyingExtensionTest`): Extend `TypeInferenceTestCase`. Test data files in `tests/Type/BeberleiAssert/data/` use `\PHPStan\Testing\assertType()` calls to verify that types are narrowed correctly after assertions. |
| 68 | + |
| 69 | +- **Rule tests** (`ImpossibleCheckTypeStaticMethodCallRuleTest`, `ImpossibleCheckTypeMethodCallRuleTest`): Extend `RuleTestCase`. These verify that PHPStan correctly reports impossible/always-true assertion checks when combined with `phpstan-strict-rules`. |
| 70 | + |
| 71 | +Test config files are loaded via `getAdditionalConfigFiles()` which returns the path to `extension.neon`. |
| 72 | + |
| 73 | +## Adding Support for New Assertions |
| 74 | + |
| 75 | +To add support for a new `Assertion::xyz()` method: |
| 76 | + |
| 77 | +1. Add a resolver entry in `AssertHelper::getExpressionResolvers()` that maps the assertion name to an equivalent PHP expression (using PhpParser AST nodes). |
| 78 | +2. Add test cases in `tests/Type/BeberleiAssert/data/data.php` using `assertType()` to verify the type narrowing. |
| 79 | +3. Run `make tests` and `make phpstan` to verify. |
| 80 | + |
| 81 | +## CI |
| 82 | + |
| 83 | +GitHub Actions workflow (`.github/workflows/build.yml`) runs on PRs and pushes to `2.0.x`: |
| 84 | + |
| 85 | +- **Lint**: PHP 7.4–8.4 |
| 86 | +- **Coding Standard**: PHP 8.2 with `phpstan/build-cs` (branch `2.x`) |
| 87 | +- **Tests**: PHP 7.4–8.4, both lowest and highest dependency versions |
| 88 | +- **PHPStan**: PHP 7.4–8.4, both lowest and highest dependency versions |
| 89 | + |
| 90 | +## Dependencies |
| 91 | + |
| 92 | +- `phpstan/phpstan: ^2.0` — The static analyser this extension plugs into |
| 93 | +- `beberlei/assert: ^3.3.0` — The assertion library (dev dependency, needed for tests) |
| 94 | +- `phpstan/phpstan-strict-rules: ^2.0` — Used for testing impossible check detection |
| 95 | +- `phpstan/phpstan-phpunit: ^2.0` — PHPUnit support for PHPStan analysis of tests |
| 96 | +- `phpunit/phpunit: ^9.6` — Test framework |
0 commit comments