Skip to content

Commit

Permalink
Merge pull request #44 from enumag/feature/messenger
Browse files Browse the repository at this point in the history
Add EnvelopeReturnTypeExtension for symfony/messenger
  • Loading branch information
lookyman authored Apr 1, 2019
2 parents 649c258 + eb878cf commit 9c7e936
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 14 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"phpstan/phpstan-phpunit": "^0.11",
"symfony/framework-bundle": "^3.0 || ^4.0",
"squizlabs/php_codesniffer": "^3.3.2",
"symfony/serializer": "^3|^4"
"symfony/serializer": "^3|^4",
"symfony/messenger": "^4.2"
},
"conflict": {
"symfony/framework-bundle": "<3.0"
Expand Down
25 changes: 15 additions & 10 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,46 @@ services:
class: PHPStan\Symfony\ServiceMapFactory
factory: PHPStan\Symfony\XmlServiceMapFactory(%symfony.container_xml_path%)
-
class: @symfony.serviceMapFactory::create()
factory: @symfony.serviceMapFactory::create()

# ControllerTrait::get()/has() return type
-
class: PHPStan\Type\Symfony\ServiceDynamicReturnTypeExtension(Symfony\Component\DependencyInjection\ContainerInterface, %symfony.constant_hassers%)
factory: PHPStan\Type\Symfony\ServiceDynamicReturnTypeExtension(Symfony\Component\DependencyInjection\ContainerInterface, %symfony.constant_hassers%)
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
-
class: PHPStan\Type\Symfony\ServiceDynamicReturnTypeExtension(Symfony\Bundle\FrameworkBundle\Controller\Controller, %symfony.constant_hassers%)
factory: PHPStan\Type\Symfony\ServiceDynamicReturnTypeExtension(Symfony\Bundle\FrameworkBundle\Controller\Controller, %symfony.constant_hassers%)
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
-
class: PHPStan\Type\Symfony\ServiceDynamicReturnTypeExtension(Symfony\Bundle\FrameworkBundle\Controller\AbstractController, %symfony.constant_hassers%)
factory: PHPStan\Type\Symfony\ServiceDynamicReturnTypeExtension(Symfony\Bundle\FrameworkBundle\Controller\AbstractController, %symfony.constant_hassers%)
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

# ControllerTrait::has() type specification
-
class: PHPStan\Type\Symfony\ServiceTypeSpecifyingExtension(Symfony\Component\DependencyInjection\ContainerInterface)
factory: PHPStan\Type\Symfony\ServiceTypeSpecifyingExtension(Symfony\Component\DependencyInjection\ContainerInterface)
tags: [phpstan.typeSpecifier.methodTypeSpecifyingExtension]
-
class: PHPStan\Type\Symfony\ServiceTypeSpecifyingExtension(Symfony\Bundle\FrameworkBundle\Controller\Controller)
factory: PHPStan\Type\Symfony\ServiceTypeSpecifyingExtension(Symfony\Bundle\FrameworkBundle\Controller\Controller)
tags: [phpstan.typeSpecifier.methodTypeSpecifyingExtension]
-
class: PHPStan\Type\Symfony\ServiceTypeSpecifyingExtension(Symfony\Bundle\FrameworkBundle\Controller\AbstractController)
factory: PHPStan\Type\Symfony\ServiceTypeSpecifyingExtension(Symfony\Bundle\FrameworkBundle\Controller\AbstractController)
tags: [phpstan.typeSpecifier.methodTypeSpecifyingExtension]

# Request::getContent() return type
-
class: PHPStan\Type\Symfony\RequestDynamicReturnTypeExtension
factory: PHPStan\Type\Symfony\RequestDynamicReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

# HeaderBag::get() return type
-
class: PHPStan\Type\Symfony\HeaderBagDynamicReturnTypeExtension
factory: PHPStan\Type\Symfony\HeaderBagDynamicReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

# SerializerInterface::deserialize() return type
-
class: PHPStan\Type\Symfony\SerializerInterfaceDynamicReturnTypeExtension
factory: PHPStan\Type\Symfony\SerializerInterfaceDynamicReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

# Envelope::all() return type
-
factory: PHPStan\Type\Symfony\EnvelopeReturnTypeExtension
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
46 changes: 46 additions & 0 deletions src/Type/Symfony/EnvelopeReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Symfony;

use PhpParser\Node\Expr\MethodCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\ArrayType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;

final class EnvelopeReturnTypeExtension implements DynamicMethodReturnTypeExtension
{

public function getClass(): string
{
return 'Symfony\Component\Messenger\Envelope';
}

public function isMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'all';
}

public function getTypeFromMethodCall(
MethodReflection $methodReflection,
MethodCall $methodCall,
Scope $scope
): Type
{
if (count($methodCall->args) === 0) {
return new ArrayType(new MixedType(), new ArrayType(new MixedType(), new ObjectType('Symfony\Component\Messenger\Stamp\StampInterface')));
}

$argType = $scope->getType($methodCall->args[0]->value);
if (!$argType instanceof ConstantStringType) {
return new ArrayType(new MixedType(), new ObjectType('Symfony\Component\Messenger\Stamp\StampInterface'));
}

return new ArrayType(new MixedType(), new ObjectType($argType->getValue()));
}

}
2 changes: 1 addition & 1 deletion tests/Symfony/NeonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function testExtensionNeon(): void
], $container->getParameters());

self::assertCount(2, $container->findByTag('phpstan.rules.rule'));
self::assertCount(6, $container->findByTag('phpstan.broker.dynamicMethodReturnTypeExtension'));
self::assertCount(7, $container->findByTag('phpstan.broker.dynamicMethodReturnTypeExtension'));
self::assertCount(3, $container->findByTag('phpstan.typeSpecifier.methodTypeSpecifyingExtension'));
self::assertInstanceOf(ServiceMap::class, $container->getByType(ServiceMap::class));
}
Expand Down
32 changes: 32 additions & 0 deletions tests/Type/Symfony/EnvelopeReturnTypeExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Symfony;

use Iterator;
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
use Symfony\Component\Messenger\Stamp\StampInterface;

final class EnvelopeReturnTypeExtensionTest extends ExtensionTestCase
{

/**
* @dataProvider getProvider
*/
public function testAll(string $expression, string $type): void
{
$this->processFile(
__DIR__ . '/envelope_all.php',
$expression,
$type,
new EnvelopeReturnTypeExtension()
);
}

public function getProvider(): Iterator
{
yield ['$test1', 'array<' . ReceivedStamp::class . '>'];
yield ['$test2', 'array<' . StampInterface::class . '>'];
yield ['$test3', 'array<array<' . StampInterface::class . '>>'];
}

}
7 changes: 5 additions & 2 deletions tests/Type/Symfony/ExtensionTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use PHPStan\Broker\AnonymousClassNameHelper;
use PHPStan\Cache\Cache;
use PHPStan\File\FileHelper;
use PHPStan\Node\InClassMethodNode;
use PHPStan\Node\VirtualNode;
use PHPStan\PhpDoc\PhpDocStringResolver;
use PHPStan\PhpDoc\TypeNodeResolver;
use PHPStan\Testing\TestCase;
Expand Down Expand Up @@ -61,7 +61,10 @@ protected function processFile(
$parser->parseFile($file),
$this->createScopeFactory($broker, $typeSpecifier)->create(ScopeContext::create($file)),
function (Node $node, Scope $scope) use ($expression, $type, &$run): void {
if ((new Standard())->prettyPrint([$node instanceof InClassMethodNode ? $node->getOriginalNode() : $node]) !== 'die') {
if ($node instanceof VirtualNode) {
return;
}
if ((new Standard())->prettyPrint([$node]) !== 'die') {
return;
}
/** @var \PhpParser\Node\Stmt\Expression $expNode */
Expand Down
9 changes: 9 additions & 0 deletions tests/Type/Symfony/envelope_all.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php declare(strict_types = 1);

$envelope = new \Symfony\Component\Messenger\Envelope(new stdClass());

$test1 = $envelope->all(\Symfony\Component\Messenger\Stamp\ReceivedStamp::class);
$test2 = $envelope->all(random_bytes(1));
$test3 = $envelope->all();

die;

0 comments on commit 9c7e936

Please sign in to comment.