Skip to content

Commit 6cba521

Browse files
authored
Add LaravelContainerMakeTypeExtension to fill Container->make() return type (#6)
1 parent ff3e2d5 commit 6cba521

File tree

7 files changed

+106
-0
lines changed

7 files changed

+106
-0
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"phpstan/phpstan": "^1.10"
99
},
1010
"require-dev": {
11+
"illuminate/container": "^10.23",
1112
"php-parallel-lint/php-parallel-lint": "^1.3",
1213
"phpstan/extension-installer": "^1.2",
1314
"phpunit/phpunit": "^10.3",

config/config.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ includes:
22
- symplify.error_formatter.neon
33

44
services:
5+
-
6+
class: Symplify\PHPStanExtensions\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension
7+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
8+
59
# Symfony Container::get($1) => $1 type
610
-
711
class: Symplify\PHPStanExtensions\TypeExtension\MethodCall\ContainerGetReturnTypeExtension
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\PHPStanExtensions\TypeExtension\MethodCall;
6+
7+
use Illuminate\Container\Container;
8+
use PhpParser\Node\Expr\MethodCall;
9+
use PHPStan\Analyser\Scope;
10+
use PHPStan\Reflection\MethodReflection;
11+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
12+
use PHPStan\Type\Type;
13+
use Symplify\PHPStanExtensions\TypeResolver\ClassConstFetchReturnTypeResolver;
14+
15+
/**
16+
* Helps to check Container->make() return type
17+
*/
18+
final class LaravelContainerMakeTypeExtension implements DynamicMethodReturnTypeExtension
19+
{
20+
public function __construct(
21+
private readonly ClassConstFetchReturnTypeResolver $classConstFetchReturnTypeResolver
22+
) {
23+
}
24+
25+
public function getClass(): string
26+
{
27+
return Container::class;
28+
}
29+
30+
public function isMethodSupported(MethodReflection $methodReflection): bool
31+
{
32+
return in_array($methodReflection->getName(), ['make', 'get'], true);
33+
}
34+
35+
public function getTypeFromMethodCall(
36+
MethodReflection $methodReflection,
37+
MethodCall $methodCall,
38+
Scope $scope
39+
): Type {
40+
return $this->classConstFetchReturnTypeResolver->resolve($methodReflection, $methodCall);
41+
}
42+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\PHPStanExtensions\Tests\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension;
6+
7+
use PHPStan\Testing\TypeInferenceTestCase;
8+
9+
final class ContainerGetReturnTypeExtensionTest extends TypeInferenceTestCase
10+
{
11+
public function testAsserts(): void
12+
{
13+
foreach ($this->gatherAssertTypes(__DIR__ . '/data/fixture.php') as [$assertType, $file, $expectedType, $actualType, $line]) {
14+
$this->assertFileAsserts($assertType, $file, ...[$expectedType, $actualType, $line]);
15+
}
16+
}
17+
18+
/**
19+
* @return string[]
20+
*/
21+
public static function getAdditionalConfigFiles(): array
22+
{
23+
return [__DIR__ . '/config/config.neon'];
24+
}
25+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\PHPStanExtensions\Tests\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension\Source;
6+
7+
final class ExternalService
8+
{
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
services:
2+
- Symplify\PHPStanExtensions\TypeResolver\ClassConstFetchReturnTypeResolver
3+
4+
-
5+
class: Symplify\PHPStanExtensions\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension
6+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Illuminate\Container\Container;
6+
use Symplify\PHPStanExtensions\Tests\TypeExtension\MethodCall\ContainerGetReturnTypeExtension\Source\ExternalService;
7+
use function PHPStan\Testing\assertType;
8+
9+
final class SomeClass
10+
{
11+
public function run(Container $container): void
12+
{
13+
$services = $container->make(ExternalService::class);
14+
assertType(ExternalService::class, $services);
15+
16+
$services = $container->get(ExternalService::class);
17+
assertType(ExternalService::class, $services);
18+
}
19+
}

0 commit comments

Comments
 (0)