Skip to content

Commit

Permalink
Add LaravelContainerMakeTypeExtension to fill Container->make() retur…
Browse files Browse the repository at this point in the history
…n type (#6)
  • Loading branch information
TomasVotruba committed Sep 17, 2023
1 parent ff3e2d5 commit 6cba521
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"phpstan/phpstan": "^1.10"
},
"require-dev": {
"illuminate/container": "^10.23",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpstan/extension-installer": "^1.2",
"phpunit/phpunit": "^10.3",
Expand Down
4 changes: 4 additions & 0 deletions config/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ includes:
- symplify.error_formatter.neon

services:
-
class: Symplify\PHPStanExtensions\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

# Symfony Container::get($1) => $1 type
-
class: Symplify\PHPStanExtensions\TypeExtension\MethodCall\ContainerGetReturnTypeExtension
Expand Down
42 changes: 42 additions & 0 deletions src/TypeExtension/MethodCall/LaravelContainerMakeTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Symplify\PHPStanExtensions\TypeExtension\MethodCall;

use Illuminate\Container\Container;
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\Type;
use Symplify\PHPStanExtensions\TypeResolver\ClassConstFetchReturnTypeResolver;

/**
* Helps to check Container->make() return type
*/
final class LaravelContainerMakeTypeExtension implements DynamicMethodReturnTypeExtension
{
public function __construct(
private readonly ClassConstFetchReturnTypeResolver $classConstFetchReturnTypeResolver
) {
}

public function getClass(): string
{
return Container::class;
}

public function isMethodSupported(MethodReflection $methodReflection): bool
{
return in_array($methodReflection->getName(), ['make', 'get'], true);
}

public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type {
return $this->classConstFetchReturnTypeResolver->resolve($methodReflection, $methodCall);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Symplify\PHPStanExtensions\Tests\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension;

use PHPStan\Testing\TypeInferenceTestCase;

final class ContainerGetReturnTypeExtensionTest extends TypeInferenceTestCase
{
public function testAsserts(): void
{
foreach ($this->gatherAssertTypes(__DIR__ . '/data/fixture.php') as [$assertType, $file, $expectedType, $actualType, $line]) {
$this->assertFileAsserts($assertType, $file, ...[$expectedType, $actualType, $line]);
}
}

/**
* @return string[]
*/
public static function getAdditionalConfigFiles(): array
{
return [__DIR__ . '/config/config.neon'];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Symplify\PHPStanExtensions\Tests\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension\Source;

final class ExternalService
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
- Symplify\PHPStanExtensions\TypeResolver\ClassConstFetchReturnTypeResolver

-
class: Symplify\PHPStanExtensions\TypeExtension\MethodCall\LaravelContainerMakeTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

use Illuminate\Container\Container;
use Symplify\PHPStanExtensions\Tests\TypeExtension\MethodCall\ContainerGetReturnTypeExtension\Source\ExternalService;
use function PHPStan\Testing\assertType;

final class SomeClass
{
public function run(Container $container): void
{
$services = $container->make(ExternalService::class);
assertType(ExternalService::class, $services);

$services = $container->get(ExternalService::class);
assertType(ExternalService::class, $services);
}
}

0 comments on commit 6cba521

Please sign in to comment.