Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
php-version: 8.3
-
name: Install dependencies
run: composer install --no-progress --prefer-dist --no-interaction
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

-
name: Install dependencies
run: composer install --no-progress --no-interaction
run: composer update --no-progress --no-interaction

-
name: Lint
Expand Down
37 changes: 17 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,46 @@ includes:


## Configuration:
- You need to mark all entrypoints of your code to get proper results.
- This is typically long whitelist of all code that is called by your framework and libraries.
- All entrypoints of your code (controllers, consumers, commands, ...) need to be known to the detector to get proper results
- By default, all overridden methods which declaration originates inside vendor are considered entrypoints
- Also, there are some basic entrypoint providers for `symfony` and `phpunit`
- For everything else, you can implement your own entrypoint provider

```neon
parameters:
deadCode:
entrypoints:
symfony:
enabled: true
phpunit:
enabled: true

services:
-
class: App\SymfonyEntrypointProvider
class: App\MyEntrypointProvider
tags:
- shipmonk.deadCode.entrypointProvider
```
```php

use ReflectionMethod;
use PHPStan\Reflection\ReflectionProvider;
use ShipMonk\PHPStan\DeadCode\Provider\EntrypointProvider;

class SymfonyEntrypointProvider implements EntrypointProvider
class MyEntrypointProvider implements EntrypointProvider
{

public function __construct(
private ReflectionProvider $reflectionProvider
) {}

public function isEntrypoint(ReflectionMethod $method): bool
{
$methodName = $method->getName();
$reflection = $this->reflectionProvider->getClass($method->getDeclaringClass()->getName());

return $reflection->is(\Symfony\Bundle\FrameworkBundle\Controller\AbstractController::class)
|| $reflection->is(\Symfony\Component\EventDispatcher\EventSubscriberInterface::class)
|| $reflection->is(\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface::class)
|| ($reflection->is(\Symfony\Component\Console\Command\Command::class) && in_array($methodName, ['execute', 'initialize', ...], true)
// and many more
return $method->getDeclaringClass()->implementsInterface(ApiOutput::class));
}
}
```

## Limitations
This project is currently a working prototype (we are using it since 2022) with limited functionality:
## Limitations:

- Only method calls are detected
- Including static methods, trait methods, interface methods, first class callables, etc.
- Callbacks like `[$this, 'method']` are mostly not detected
- Callbacks like `[$this, 'method']` are mostly not detected; prefer first class callables `$this->method(...)`
- Any calls on mixed types are not detected, e.g. `$unknownClass->method()`
- Expression method calls are not detected, e.g. `$this->$methodName()`
- Anonymous classes are ignored
Expand Down
11 changes: 7 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
],
"require": {
"php": "^7.4 || ^8.0",
"phpstan/phpstan": "^1.10.30"
"phpstan/phpstan": "^1.11.0"
},
"require-dev": {
"editorconfig-checker/editorconfig-checker": "^10.3.0",
Expand All @@ -22,8 +22,11 @@
"phpstan/phpstan-strict-rules": "^1.2.3",
"phpunit/phpunit": "^9.5.20",
"shipmonk/name-collision-detector": "^2.0.0",
"shipmonk/phpstan-rules": "^2.11",
"slevomat/coding-standard": "^8.0.1"
"shipmonk/phpstan-rules": "^3.1",
"slevomat/coding-standard": "^8.0.1",
"symfony/contracts": "^2.5 || ^3.0",
"symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0",
"symfony/routing": "^5.4 || ^6.0 || ^7.0"
},
"autoload": {
"psr-4": {
Expand Down Expand Up @@ -65,7 +68,7 @@
"check:composer": "composer normalize --dry-run --no-check-lock --no-update-lock",
"check:cs": "phpcs",
"check:ec": "ec src tests",
"check:tests": "phpunit -vvv tests",
"check:tests": "phpunit tests",
"check:types": "phpstan analyse -vvv --ansi",
"fix:cs": "phpcbf"
}
Expand Down
Loading