Skip to content

Commit 18f462f

Browse files
authored
Merge branch 'master' into union-properties-array
2 parents 7a8b0e9 + f8adbc4 commit 18f462f

File tree

14 files changed

+143
-12
lines changed

14 files changed

+143
-12
lines changed

composer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"doctrine/instantiator": "^1.3.1 || ^2.0",
2727
"doctrine/lexer": "^2.0 || ^3.0",
2828
"jms/metadata": "^2.6",
29-
"phpstan/phpdoc-parser": "^1.20"
29+
"phpstan/phpdoc-parser": "^1.20 || ^2.0"
3030
},
3131
"suggest": {
3232
"doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.",
@@ -37,17 +37,18 @@
3737
"require-dev": {
3838
"ext-pdo_sqlite": "*",
3939
"doctrine/annotations": "^1.14 || ^2.0",
40+
"slevomat/coding-standard": "dev-master#f2cc4c553eae68772624ffd7dd99022343b69c31 as 8.11.9999",
4041
"doctrine/coding-standard": "^12.0",
4142
"doctrine/orm": "^2.14 || ^3.0",
4243
"doctrine/persistence": "^2.5.2 || ^3.0",
4344
"doctrine/phpcr-odm": "^1.5.2 || ^2.0",
4445
"jackalope/jackalope-doctrine-dbal": "^1.3",
4546
"ocramius/proxy-manager": "^1.0 || ^2.0",
4647
"phpbench/phpbench": "^1.0",
47-
"phpstan/phpstan": "^1.10.57",
48+
"phpstan/phpstan": "^2.0",
4849
"phpunit/phpunit": "^9.0 || ^10.0 || ^11.0",
4950
"psr/container": "^1.0 || ^2.0",
50-
"rector/rector": "^1.0.0",
51+
"rector/rector": "^1.0.0 || ^2.0@dev",
5152
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
5253
"symfony/expression-language": "^5.4 || ^6.0 || ^7.0",
5354
"symfony/filesystem": "^5.4 || ^6.0 || ^7.0",

phpstan.neon.dist

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ parameters:
1414
- '#^Property JMS\\Serializer\\Handler\\FormErrorHandler\:\:\$translator has unknown class Symfony\\Component\\Translation\\TranslatorInterface as its type\.$#'
1515
- '#^Cannot call method appendChild\(\) on null\.$#'
1616
- '#^Call to an undefined method JMS\\Serializer\\VisitorInterface\:\:setData\(\)\.$#'
17-
- '#^Property JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\CollectionOfNotExistingClasses\:\:\$productIds has unknown class JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\NotExistingClass as its type\.$#'
1817
- '#^Call to method expects\(\) on an unknown class Symfony\\Component\\Translation\\TranslatorInterface\.$#'
1918
- '#^Call to an undefined method JMS\\Serializer\\VisitorInterface\:\:hasData\(\)\.$#'
20-
- '#^Property JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\CollectionOfClassesWithFullNamespacePath\:\:\$productIds has unknown class JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\Product as its type\.$#'
21-
- '#^Property JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\CollectionOfInterfacesWithFullNamespacePath\:\:\$productColors has unknown class JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\Details\\ProductColor as its type\.$#'
2219
- '#^Method JMS\\Serializer\\GraphNavigator\\DeserializationGraphNavigator\:\:resolveMetadata\(\) should return JMS\\Serializer\\Metadata\\ClassMetadata\|null#'
20+
- '#^ArrayObject<\*NEVER\*, \*NEVER\*> does not accept list<string\|null>\.#'
21+
- '#^ArrayObject<\*NEVER\*, \*NEVER\*> does not accept array<string, ArrayObject>\.#'
2322
paths:
2423
- %currentWorkingDirectory%/src
2524
- %currentWorkingDirectory%/tests
25+
excludePaths:
26+
- tests/Fixtures/*
27+
reportUnmatchedIgnoredErrors: false

phpstan/no-typed-prop.neon

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ parameters:
88
- %currentWorkingDirectory%/tests/Fixtures/DocBlockType/Collection/ConstructorPropertyPromotion.php
99
- %currentWorkingDirectory%/tests/Fixtures/DocBlockType/Collection/ConstructorPropertyPromotionWithoutDocblock.php
1010
- %currentWorkingDirectory%/tests/Fixtures/DocBlockType/Collection/ConstructorPropertyPromotionWithScalar.php
11-
- %currentWorkingDirectory%/tests/Serializer/BaseSerializationTest.php

phpstan/no-unions.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
parameters:
22
excludePaths:
3+
- %currentWorkingDirectory%/src/Handler/UnionHandler.php
34
- %currentWorkingDirectory%/tests/Fixtures/TypedProperties/ComplexDiscriminatedUnion.php

src/GraphNavigator/DeserializationGraphNavigator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ public function accept($data, ?array $type = null)
128128

129129
case 'bool':
130130
case 'boolean':
131+
case 'false':
132+
case 'true':
131133
return $this->visitor->visitBoolean($data, $type);
132134

133135
case 'double':

src/GraphNavigator/SerializationGraphNavigator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ public function accept($data, ?array $type = null)
156156

157157
case 'bool':
158158
case 'boolean':
159+
case 'true':
160+
case 'false':
159161
return $this->visitor->visitBoolean((bool) $data, $type);
160162

161163
case 'double':

src/Handler/FormErrorHandler.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ private function getErrorMessage(FormError $error): ?string
129129

130130
private function convertFormToArray(SerializationVisitorInterface $visitor, FormInterface $data): \ArrayObject
131131
{
132-
/** @var \ArrayObject{errors?:array<string>,children?:array<string,\ArrayObject>} $form */
133132
$form = new \ArrayObject();
134133
$errors = [];
135134
foreach ($data->getErrors() as $error) {

src/Metadata/Driver/DocBlockDriver/DocBlockTypeResolver.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use PHPStan\PhpDocParser\Parser\PhpDocParser;
2121
use PHPStan\PhpDocParser\Parser\TokenIterator;
2222
use PHPStan\PhpDocParser\Parser\TypeParser;
23+
use PHPStan\PhpDocParser\ParserConfig;
2324

2425
/**
2526
* @internal
@@ -47,11 +48,25 @@ final class DocBlockTypeResolver
4748

4849
public function __construct()
4950
{
50-
$constExprParser = new ConstExprParser();
51-
$typeParser = new TypeParser($constExprParser);
51+
// PHPStan PHPDoc Parser 2
52+
if (class_exists(ParserConfig::class)) {
53+
$config = new ParserConfig(['lines' => true, 'indexes' => true]);
5254

53-
$this->phpDocParser = new PhpDocParser($typeParser, $constExprParser);
54-
$this->lexer = new Lexer();
55+
$constExprParser = new ConstExprParser($config);
56+
$typeParser = new TypeParser($config, $constExprParser);
57+
58+
$this->phpDocParser = new PhpDocParser($config, $typeParser, $constExprParser);
59+
$this->lexer = new Lexer($config);
60+
} else {
61+
// @phpstan-ignore arguments.count
62+
$constExprParser = new ConstExprParser();
63+
// @phpstan-ignore arguments.count
64+
$typeParser = new TypeParser($constExprParser);
65+
// @phpstan-ignore arguments.count
66+
$this->phpDocParser = new PhpDocParser($typeParser, $constExprParser);
67+
// @phpstan-ignore arguments.count
68+
$this->lexer = new Lexer();
69+
}
5570
}
5671

5772
/**

src/Metadata/Driver/TypedPropertiesDriver.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ private function getDefaultWhiteList(): array
7575
'float',
7676
'bool',
7777
'boolean',
78+
'true',
79+
'false',
7880
'string',
7981
'double',
8082
'iterable',

tests/Fixtures/DataFalse.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JMS\Serializer\Tests\Fixtures;
6+
7+
class DataFalse
8+
{
9+
public false $data;
10+
11+
public function __construct(
12+
false $data
13+
) {
14+
$this->data = $data;
15+
}
16+
}

tests/Fixtures/DataTrue.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace JMS\Serializer\Tests\Fixtures;
6+
7+
class DataTrue
8+
{
9+
public true $data;
10+
11+
public function __construct(
12+
true $data
13+
) {
14+
$this->data = $data;
15+
}
16+
}

tests/Fixtures/TypedProperties/UnionTypedProperties.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ class UnionTypedProperties
1010

1111
private int|bool|float|string|null $nullableData;
1212

13+
private string|false $valueTypedUnion;
14+
1315
public function __construct($data)
1416
{
1517
$this->data = $data;

tests/Metadata/Driver/UnionTypedPropertiesDriverTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,31 @@ public function testInferUnionTypesShouldResultInManyTypes()
6161
);
6262
}
6363

64+
public function testInferUnionTypesShouldIncludeValueTypes()
65+
{
66+
$m = $this->resolve(UnionTypedProperties::class);
67+
68+
self::assertEquals(
69+
[
70+
'name' => 'union',
71+
'params' =>
72+
[
73+
[
74+
[
75+
'name' => 'string',
76+
'params' => [],
77+
],
78+
[
79+
'name' => 'false',
80+
'params' => [],
81+
],
82+
],
83+
],
84+
],
85+
$m->propertyMetadata['valueTypedUnion']->type,
86+
);
87+
}
88+
6489
private function resolve(string $classToResolve): ClassMetadata
6590
{
6691
$namingStrategy = new IdenticalPropertyNamingStrategy();

tests/Serializer/JsonSerializationTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use JMS\Serializer\SerializationContext;
1616
use JMS\Serializer\Tests\Fixtures\Author;
1717
use JMS\Serializer\Tests\Fixtures\AuthorList;
18+
use JMS\Serializer\Tests\Fixtures\DataFalse;
19+
use JMS\Serializer\Tests\Fixtures\DataTrue;
1820
use JMS\Serializer\Tests\Fixtures\DiscriminatedAuthor;
1921
use JMS\Serializer\Tests\Fixtures\DiscriminatedComment;
2022
use JMS\Serializer\Tests\Fixtures\FirstClassMapCollection;
@@ -27,6 +29,7 @@
2729
use JMS\Serializer\Visitor\Factory\JsonSerializationVisitorFactory;
2830
use JMS\Serializer\Visitor\SerializationVisitorInterface;
2931
use PHPUnit\Framework\Attributes\DataProvider;
32+
use TypeError;
3033

3134
class JsonSerializationTest extends BaseSerializationTestCase
3235
{
@@ -152,6 +155,8 @@ protected static function getContent($key)
152155
$outputs['data_bool'] = '{"data":false}';
153156
$outputs['data_string'] = '{"data":"foo"}';
154157
$outputs['data_array'] = '{"data":[1,2,3]}';
158+
$outputs['data_true'] = '{"data":true}';
159+
$outputs['data_false'] = '{"data":false}';
155160
$outputs['data_author'] = '{"data":{"full_name":"foo"}}';
156161
$outputs['data_comment'] = '{"data":{"author":{"full_name":"foo"},"text":"bar"}}';
157162
$outputs['data_discriminated_author'] = '{"data":{"full_name":"foo","objectType":"author"}}';
@@ -465,6 +470,50 @@ public function testUnionProperties($data, string $expected): void
465470
self::assertEquals($this->serialize($object), static::getContent($expected));
466471
}
467472

473+
public function testTrueDataType()
474+
{
475+
if (PHP_VERSION_ID < 80200) {
476+
$this->markTestSkipped('True type requires PHP 8.2');
477+
478+
return;
479+
}
480+
481+
self::assertEquals(
482+
static::getContent('data_true'),
483+
$this->serialize(new DataTrue(true)),
484+
);
485+
486+
self::assertEquals(
487+
new DataTrue(true),
488+
$this->deserialize(static::getContent('data_true'), DataTrue::class),
489+
);
490+
491+
$this->expectException(TypeError::class);
492+
$this->deserialize(static::getContent('data_false'), DataTrue::class);
493+
}
494+
495+
public function testFalseDataType()
496+
{
497+
if (PHP_VERSION_ID < 80200) {
498+
$this->markTestSkipped('False type requires PHP 8.2');
499+
500+
return;
501+
}
502+
503+
self::assertEquals(
504+
static::getContent('data_false'),
505+
$this->serialize(new DataFalse(false)),
506+
);
507+
508+
self::assertEquals(
509+
new DataFalse(false),
510+
$this->deserialize(static::getContent('data_false'), DataFalse::class),
511+
);
512+
513+
$this->expectException(TypeError::class);
514+
$this->deserialize(static::getContent('data_true'), DataFalse::class);
515+
}
516+
468517
public function testDeserializingComplexDiscriminatedUnionProperties()
469518
{
470519
if (PHP_VERSION_ID < 80000) {

0 commit comments

Comments
 (0)