Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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
47 changes: 47 additions & 0 deletions src/Type/Symfony/EnvelopeReturnTypeExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?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;
use Symfony\Component\Messenger\Stamp\StampInterface;

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(StampInterface::class)));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StampInterface needs to be a string here, so that composer require checker doesn't complain. I know, not ideal.

}

$argType = $scope->getType($methodCall->args[0]->value);
if (!$argType instanceof ConstantStringType) {
return new ArrayType(new MixedType(), new ObjectType(StampInterface::class));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and here...

}

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

}
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 . '>>'];
}

}
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));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any better way to pass a "non-constant-string" in this test?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is fine.

$test3 = $envelope->all();

die;