Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d292842

Browse filesBrowse files
committed
Add support for Serializer::deserialize
1 parent a364099 commit d292842
Copy full SHA for d292842

File tree

Expand file treeCollapse file tree

6 files changed

+90
-2
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+90
-2
lines changed

‎composer.json

Copy file name to clipboardExpand all lines: composer.json
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"slevomat/coding-standard": "^4.5.2",
3333
"phpstan/phpstan-phpunit": "^0.11",
3434
"symfony/framework-bundle": "^3.0 || ^4.0",
35-
"squizlabs/php_codesniffer": "^3.3.2"
35+
"squizlabs/php_codesniffer": "^3.3.2",
36+
"symfony/serializer": "^3|^4"
3637
},
3738
"conflict": {
3839
"symfony/framework-bundle": "<3.0"

‎extension.neon

Copy file name to clipboardExpand all lines: extension.neon
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ services:
4545
-
4646
class: PHPStan\Type\Symfony\HeaderBagDynamicReturnTypeExtension
4747
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
48+
49+
# SerializerInterface::deserialize() return type
50+
-
51+
class: PHPStan\Type\Symfony\SerializerInterfaceDynamicReturnTypeExtension
52+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Symfony;
4+
5+
use PhpParser\Node\Expr\MethodCall;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Reflection\MethodReflection;
8+
use PHPStan\Type\ArrayType;
9+
use PHPStan\Type\Constant\ConstantStringType;
10+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
11+
use PHPStan\Type\MixedType;
12+
use PHPStan\Type\ObjectType;
13+
use PHPStan\Type\Type;
14+
15+
class SerializerInterfaceDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
16+
{
17+
18+
public function getClass(): string
19+
{
20+
return 'Symfony\Component\Serializer\SerializerInterface';
21+
}
22+
23+
public function isMethodSupported(MethodReflection $methodReflection): bool
24+
{
25+
return $methodReflection->getName() === 'deserialize';
26+
}
27+
28+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
29+
{
30+
$argType = $scope->getType($methodCall->args[1]->value);
31+
if (!$argType instanceof ConstantStringType) {
32+
return new MixedType();
33+
}
34+
35+
$objectName = $argType->getValue();
36+
37+
if (substr($objectName, -2) === '[]') {
38+
// The key type is determined by the data
39+
return new ArrayType(new MixedType(false), new ObjectType(substr($objectName, 0, -2)));
40+
}
41+
42+
return new ObjectType($objectName);
43+
}
44+
45+
}

‎tests/Symfony/NeonTest.php

Copy file name to clipboardExpand all lines: tests/Symfony/NeonTest.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function testExtensionNeon(): void
4040
], $container->getParameters());
4141

4242
self::assertCount(2, $container->findByTag('phpstan.rules.rule'));
43-
self::assertCount(5, $container->findByTag('phpstan.broker.dynamicMethodReturnTypeExtension'));
43+
self::assertCount(6, $container->findByTag('phpstan.broker.dynamicMethodReturnTypeExtension'));
4444
self::assertCount(3, $container->findByTag('phpstan.typeSpecifier.methodTypeSpecifyingExtension'));
4545
self::assertInstanceOf(ServiceMap::class, $container->getByType(ServiceMap::class));
4646
}
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Symfony;
4+
5+
use Iterator;
6+
7+
final class SerializerInterfaceDynamicReturnTypeExtensionTest extends ExtensionTestCase
8+
{
9+
10+
/**
11+
* @dataProvider getContentProvider
12+
*/
13+
public function testGetContent(string $expression, string $type): void
14+
{
15+
$this->processFile(
16+
__DIR__ . '/serializer.php',
17+
$expression,
18+
$type,
19+
new SerializerInterfaceDynamicReturnTypeExtension()
20+
);
21+
}
22+
23+
public function getContentProvider(): Iterator
24+
{
25+
yield ['$first', 'Bar'];
26+
yield ['$second', 'array<Bar>'];
27+
}
28+
29+
}

‎tests/Type/Symfony/serializer.php

Copy file name to clipboard
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php declare(strict_types = 1);
2+
3+
$serializer = new \Symfony\Component\Serializer\Serializer();
4+
5+
$first = $serializer->deserialize('bar', 'Bar', 'format');
6+
$second = $serializer->deserialize('bar', 'Bar[]', 'format');
7+
8+
die;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.