Skip to content

Commit 7ed37e6

Browse files
committed
unify symfony context
1 parent a0aa7de commit 7ed37e6

13 files changed

+112
-85
lines changed

src/Symfony/Component/SerDes/Context/ContextBuilder/Deserialize/DeserializeFormatterAttributeContextBuilder.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
final class DeserializeFormatterAttributeContextBuilder implements DeserializeContextBuilderInterface
2424
{
2525
/**
26-
* @var array<string, array{deserialize: callable}>
26+
* @var array<class-string, array<string, callable>>|null
2727
*/
2828
private static ?array $cache = null;
2929

@@ -44,15 +44,15 @@ public function build(array $context): array
4444
self::$cache = $propertyFormatters;
4545
}
4646

47-
$context['_symfony']['property_formatter'] = self::$cache;
47+
$context['_symfony']['deserialize']['property_formatter'] = self::$cache;
4848

4949
return $context;
5050
}
5151

5252
/**
5353
* @param class-string $className
5454
*
55-
* @return array<string, array{deserialize: callable}>
55+
* @return array<class-string, array<string, callable>>
5656
*/
5757
private function propertyFormatters(string $className): array
5858
{
@@ -71,7 +71,7 @@ private function propertyFormatters(string $className): array
7171
break;
7272
}
7373

74-
$propertyFormatters[sprintf('%s::$%s', $property->getDeclaringClass()->getName(), $property->getName())]['deserialize'] = $attributeInstance->onDeserialize;
74+
$propertyFormatters[$property->getDeclaringClass()->getName()][$property->getName()] = $attributeInstance->onDeserialize;
7575

7676
break;
7777
}

src/Symfony/Component/SerDes/Context/ContextBuilder/Deserialize/DeserializeNameAttributeContextBuilder.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
final class DeserializeNameAttributeContextBuilder implements DeserializeContextBuilderInterface
2424
{
2525
/**
26-
* @var array<string, string>
26+
* @var array<class-string, array<string, string>>|null
2727
*/
2828
private static ?array $cache = null;
2929

@@ -44,15 +44,15 @@ public function build(array $context): array
4444
self::$cache = $propertyNames;
4545
}
4646

47-
$context['_symfony']['property_name'] = self::$cache;
47+
$context['_symfony']['deserialize']['property_name'] = self::$cache;
4848

4949
return $context;
5050
}
5151

5252
/**
5353
* @param class-string $className
5454
*
55-
* @return array<string, string>
55+
* @return array<class-string, array<string, string>>
5656
*/
5757
private function propertyNames(string $className): array
5858
{
@@ -67,7 +67,7 @@ private function propertyNames(string $className): array
6767
/** @var Name $attributeInstance */
6868
$attributeInstance = $attribute->newInstance();
6969

70-
$propertyNames[sprintf('%s[%s]', $property->getDeclaringClass()->getName(), $attributeInstance->name)] = $property->getName();
70+
$propertyNames[$property->getDeclaringClass()->getName()][$attributeInstance->name] = $property->getName();
7171

7272
break;
7373
}

src/Symfony/Component/SerDes/Context/ContextBuilder/Serialize/SerializeFormatterAttributeContextBuilder.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
final class SerializeFormatterAttributeContextBuilder implements SerializeContextBuilderInterface
2424
{
2525
/**
26-
* @var array<string, array{serialize: callable}>
26+
* @var array<class-string, array<string, callable>>|null
2727
*/
2828
private static ?array $cache = null;
2929

@@ -48,15 +48,15 @@ public function build(array $context): array
4848
self::$cache = $propertyFormatters;
4949
}
5050

51-
$context['_symfony']['property_formatter'] = self::$cache;
51+
$context['_symfony']['serialize']['property_formatter'] = self::$cache;
5252

5353
return $context;
5454
}
5555

5656
/**
5757
* @param class-string $className
5858
*
59-
* @return array<string, array{serialize: callable}>
59+
* @return array<class-string, array<string, callable>>
6060
*/
6161
private function propertyFormatters(string $className): array
6262
{
@@ -75,7 +75,7 @@ private function propertyFormatters(string $className): array
7575
break;
7676
}
7777

78-
$propertyFormatters[sprintf('%s::$%s', $property->getDeclaringClass()->getName(), $property->getName())]['serialize'] = $attributeInstance->onSerialize;
78+
$propertyFormatters[$property->getDeclaringClass()->getName()][$property->getName()] = $attributeInstance->onSerialize;
7979

8080
break;
8181
}

src/Symfony/Component/SerDes/Context/ContextBuilder/Serialize/SerializeNameAttributeContextBuilder.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
final class SerializeNameAttributeContextBuilder implements SerializeContextBuilderInterface
2424
{
2525
/**
26-
* @var array<string, string>
26+
* @var array<class-string, array<string, string>>|null
2727
*/
2828
private static ?array $cache = null;
2929

@@ -48,15 +48,15 @@ public function build(array $context): array
4848
self::$cache = $propertyNames;
4949
}
5050

51-
$context['_symfony']['property_name'] = self::$cache;
51+
$context['_symfony']['serialize']['property_name'] = self::$cache;
5252

5353
return $context;
5454
}
5555

5656
/**
5757
* @param class-string $className
5858
*
59-
* @return array<string, string>
59+
* @return array<class-string, array<string, string>>
6060
*/
6161
private function propertyNames(string $className): array
6262
{
@@ -71,7 +71,7 @@ private function propertyNames(string $className): array
7171
/** @var Name $attributeInstance */
7272
$attributeInstance = $attribute->newInstance();
7373

74-
$propertyNames[sprintf('%s::$%s', $property->getDeclaringClass()->getName(), $property->getName())] = $attributeInstance->name;
74+
$propertyNames[$property->getDeclaringClass()->getName()][$property->getName()] = $attributeInstance->name;
7575

7676
break;
7777
}

src/Symfony/Component/SerDes/Hook/Deserialize/PropertyHook.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ public function __invoke(\ReflectionClass $class, string $key, callable $value,
4242
$propertyClass = $class->getName();
4343

4444
/** @var string $propertyName */
45-
$propertyName = $context['_symfony']['property_name'][sprintf('%s[%s]', $propertyClass, $key)] ?? $key;
46-
$cacheKey = $propertyIdentifier = $propertyClass.'::$'.$propertyName;
45+
$propertyName = $context['_symfony']['deserialize']['property_name'][$propertyClass][$key] ?? $key;
46+
$cacheKey = $propertyClass.'::$'.$propertyName;
4747

4848
if (!self::$cache['class_has_property'][$cacheKey] = self::$cache['class_has_property'][$cacheKey] ?? $class->hasProperty($propertyName)) {
4949
return [];
5050
}
5151

52-
if (!isset($context['_symfony']['property_formatter'][$propertyIdentifier]['deserialize'])) {
52+
if (!isset($context['_symfony']['deserialize']['property_formatter'][$propertyClass][$key])) {
5353
$valueType = self::$cache['value_type'][$cacheKey] = self::$cache['value_type'][$cacheKey] ?? $this->typeExtractor->extractFromProperty(new \ReflectionProperty($propertyClass, $propertyName));
5454

5555
if (isset($context['_symfony']['generic_parameter_types'][$propertyClass])) {
@@ -62,9 +62,9 @@ public function __invoke(\ReflectionClass $class, string $key, callable $value,
6262
];
6363
}
6464

65-
$cacheKey .= ($propertyFormatterHash = json_encode($context['_symfony']['property_formatter'][$propertyIdentifier]['deserialize']));
65+
$cacheKey .= ($propertyFormatterHash = json_encode($context['_symfony']['deserialize']['property_formatter'][$propertyClass][$key]));
6666

67-
$propertyFormatter = \Closure::fromCallable($context['_symfony']['property_formatter'][$propertyIdentifier]['deserialize']);
67+
$propertyFormatter = \Closure::fromCallable($context['_symfony']['deserialize']['property_formatter'][$propertyClass][$key]);
6868
$propertyFormatterReflection = new \ReflectionFunction($propertyFormatter);
6969

7070
$valueType = self::$cache['value_type'][$cacheKey] = self::$cache['value_type'][$cacheKey] ?? $this->typeExtractor->extractFromFunctionParameter($propertyFormatterReflection->getParameters()[0]);

src/Symfony/Component/SerDes/Hook/Serialize/PropertyHook.php

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,26 @@ public function __construct(
3131

3232
public function __invoke(\ReflectionProperty $property, string $accessor, array $context): array
3333
{
34-
$propertyIdentifier = sprintf('%s::$%s', $property->getDeclaringClass()->getName(), $property->getName());
35-
36-
$propertyFormatter = isset($context['_symfony']['property_formatter'][$propertyIdentifier]['serialize'])
37-
? new \ReflectionFunction(\Closure::fromCallable($context['_symfony']['property_formatter'][$propertyIdentifier]['serialize']))
34+
$propertyFormatter = isset($context['_symfony']['serialize']['property_formatter'][$className = $property->getDeclaringClass()->getName()][$name = $property->getName()])
35+
? new \ReflectionFunction(\Closure::fromCallable($context['_symfony']['serialize']['property_formatter'][$className][$name]))
3836
: null;
3937

4038
return [
41-
'name' => $this->name($property, $propertyIdentifier, $context),
39+
'name' => $this->name($property, $className, $name, $context),
4240
'type' => $this->type($property, $propertyFormatter, $context),
43-
'accessor' => $this->accessor($propertyIdentifier, $propertyFormatter, $accessor, $context),
41+
'accessor' => $this->accessor($className, $name, $propertyFormatter, $accessor, $context),
4442
'context' => $context,
4543
];
4644
}
4745

4846
/**
47+
* @param class-string $className
4948
* @param array<string, mixed> $context
5049
*/
51-
private function name(\ReflectionProperty $property, string $propertyIdentifier, array $context): string
50+
private function name(\ReflectionProperty $property, string $className, string $name, array $context): string
5251
{
53-
$name = $property->getName();
54-
55-
if (isset($context['_symfony']['property_name'][$propertyIdentifier])) {
56-
$name = $context['_symfony']['property_name'][$propertyIdentifier];
52+
if (isset($context['_symfony']['serialize']['property_name'][$className][$name])) {
53+
return $context['_symfony']['serialize']['property_name'][$className][$name];
5754
}
5855

5956
return $name;
@@ -84,27 +81,28 @@ private function type(\ReflectionProperty $property, ?\ReflectionFunction $prope
8481
}
8582

8683
/**
84+
* @param class-string $className
8785
* @param array<string, mixed> $context
8886
*/
89-
private function accessor(string $propertyIdentifier, ?\ReflectionFunction $propertyFormatter, string $accessor, array $context): string
87+
private function accessor(string $className, string $name, ?\ReflectionFunction $propertyFormatter, string $accessor, array $context): string
9088
{
9189
if (null === $propertyFormatter) {
9290
return $accessor;
9391
}
9492

9593
if (!$propertyFormatter->getClosureScopeClass()?->hasMethod($propertyFormatter->getName()) || !$propertyFormatter->isStatic()) {
96-
throw new InvalidArgumentException(sprintf('Property formatter "%s" must be a static method.', $propertyIdentifier));
94+
throw new InvalidArgumentException(sprintf('Property formatter "%s" must be a static method.', sprintf('%s::$%s', $className, $name)));
9795
}
9896

9997
if (($returnType = $propertyFormatter->getReturnType()) instanceof \ReflectionNamedType && ('void' === $returnType->getName() || 'never' === $returnType->getName())) {
100-
throw new InvalidArgumentException(sprintf('Return type of property formatter "%s" must not be "void" nor "never".', $propertyIdentifier));
98+
throw new InvalidArgumentException(sprintf('Return type of property formatter "%s" must not be "void" nor "never".', sprintf('%s::$%s', $className, $name)));
10199
}
102100

103101
if (null !== ($contextParameter = $propertyFormatter->getParameters()[1] ?? null)) {
104102
$contextParameterType = $contextParameter->getType();
105103

106104
if (!$contextParameterType instanceof \ReflectionNamedType || 'array' !== $contextParameterType->getName()) {
107-
throw new InvalidArgumentException(sprintf('Second argument of property formatter "%s" must be an array.', $propertyIdentifier));
105+
throw new InvalidArgumentException(sprintf('Second argument of property formatter "%s" must be an array.', sprintf('%s::$%s', $className, $name)));
108106
}
109107
}
110108

src/Symfony/Component/SerDes/Tests/Attribute/FormatterTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\SerDes\Attribute\Formatter;
16-
use Symfony\Component\SerDes\Exception\InvalidArgumentException;
1716

1817
class FormatterTest extends TestCase
1918
{

src/Symfony/Component/SerDes/Tests/Context/ContextBuilder/Deserialize/DeserializeFormatterAttributeContextBuilderTest.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ public function testAddPropertyFormattersToContext()
3131

3232
$expectedContext = [
3333
'_symfony' => [
34-
'property_formatter' => [
35-
sprintf('%s::$id', DummyWithFormatterAttributes::class) => [
36-
'deserialize' => [DummyWithFormatterAttributes::class, 'divideAndCastToInt'],
37-
],
38-
sprintf('%s::$name', AnotherDummyWithFormatterAttributes::class) => [
39-
'deserialize' => [AnotherDummyWithFormatterAttributes::class, 'lowercase'],
34+
'deserialize' => [
35+
'property_formatter' => [
36+
DummyWithFormatterAttributes::class => [
37+
'id' => [DummyWithFormatterAttributes::class, 'divideAndCastToInt'],
38+
],
39+
AnotherDummyWithFormatterAttributes::class => [
40+
'name' => [AnotherDummyWithFormatterAttributes::class, 'lowercase'],
41+
],
4042
],
4143
],
4244
],

src/Symfony/Component/SerDes/Tests/Context/ContextBuilder/Deserialize/DeserializeNameAttributeContextBuilderTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ public function testAddPropertyNameToContext()
3131

3232
$expectedContext = [
3333
'_symfony' => [
34-
'property_name' => [
35-
sprintf('%s[@id]', DummyWithNameAttributes::class) => 'id',
36-
sprintf('%s[call_me_with]', AnotherDummyWithNameAttributes::class) => 'name',
34+
'deserialize' => [
35+
'property_name' => [
36+
DummyWithNameAttributes::class => ['@id' => 'id'],
37+
AnotherDummyWithNameAttributes::class => ['call_me_with' => 'name'],
38+
],
3739
],
3840
],
3941
];

src/Symfony/Component/SerDes/Tests/Context/ContextBuilder/Serialize/SerializeFormatterAttributeContextBuilderTest.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ public function testAddPropertyFormattersToContext()
3131

3232
$expectedContext = [
3333
'_symfony' => [
34-
'property_formatter' => [
35-
sprintf('%s::$id', DummyWithFormatterAttributes::class) => [
36-
'serialize' => [DummyWithFormatterAttributes::class, 'doubleAndCastToString'],
37-
],
38-
sprintf('%s::$name', AnotherDummyWithFormatterAttributes::class) => [
39-
'serialize' => [AnotherDummyWithFormatterAttributes::class, 'uppercase'],
34+
'serialize' => [
35+
'property_formatter' => [
36+
DummyWithFormatterAttributes::class => [
37+
'id' => [DummyWithFormatterAttributes::class, 'doubleAndCastToString'],
38+
],
39+
AnotherDummyWithFormatterAttributes::class => [
40+
'name' => [AnotherDummyWithFormatterAttributes::class, 'uppercase'],
41+
],
4042
],
4143
],
4244
],

src/Symfony/Component/SerDes/Tests/Context/ContextBuilder/Serialize/SerializeNameAttributeContextBuilderTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ public function testAddPropertyNameToContext()
3131

3232
$expectedContext = [
3333
'_symfony' => [
34-
'property_name' => [
35-
sprintf('%s::$id', DummyWithNameAttributes::class) => '@id',
36-
sprintf('%s::$name', AnotherDummyWithNameAttributes::class) => 'call_me_with',
34+
'serialize' => [
35+
'property_name' => [
36+
DummyWithNameAttributes::class => ['id' => '@id'],
37+
AnotherDummyWithNameAttributes::class => ['name' => 'call_me_with'],
38+
],
3739
],
3840
],
3941
];

src/Symfony/Component/SerDes/Tests/Hook/Deserialize/PropertyHookTest.php

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@ public function testRetrievePropertyName()
2929

3030
$context = [
3131
'_symfony' => [
32-
'property_name' => [
33-
sprintf('%s[@id]', ClassicDummy::class) => 'id',
32+
'deserialize' => [
33+
'property_name' => [
34+
ClassicDummy::class => [
35+
'@id' => 'id',
36+
],
37+
],
3438
],
3539
],
3640
];
@@ -98,9 +102,11 @@ public function testRetrievePropertyTypeWithFormatter()
98102

99103
$context = [
100104
'_symfony' => [
101-
'property_formatter' => [
102-
sprintf('%s::$name', ClassicDummy::class) => [
103-
'deserialize' => fn (int $v, array $c): string => (string) $v,
105+
'deserialize' => [
106+
'property_formatter' => [
107+
ClassicDummy::class => [
108+
'name' => fn (int $v, array $c): string => (string) $v,
109+
],
104110
],
105111
],
106112
],
@@ -128,9 +134,11 @@ public function testRetrievePropertyTypeWithFormatterAndGenerics()
128134
'generic_parameter_types' => [
129135
DummyWithFormatterAttributes::class => ['T' => 'string'],
130136
],
131-
'property_formatter' => [
132-
sprintf('%s::$name', DummyWithFormatterAttributes::class) => [
133-
'deserialize' => DummyWithFormatterAttributes::doubleAndCastToString(...),
137+
'deserialize' => [
138+
'property_formatter' => [
139+
DummyWithFormatterAttributes::class => [
140+
'name' => DummyWithFormatterAttributes::doubleAndCastToString(...),
141+
],
134142
],
135143
],
136144
],
@@ -158,9 +166,11 @@ public function testDoNotReplaceGenericTypesWhenFormatterDoesNotBelongToCurrentC
158166
'generic_parameter_types' => [
159167
DummyWithQuotes::class => ['T' => 'string'],
160168
],
161-
'property_formatter' => [
162-
sprintf('%s::$name', DummyWithQuotes::class) => [
163-
'deserialize' => fn (mixed $v, array $c): string => (string) $v,
169+
'deserialize' => [
170+
'property_formatter' => [
171+
DummyWithQuotes::class => [
172+
'name' => fn (mixed $v, array $c): string => (string) $v,
173+
],
164174
],
165175
],
166176
],
@@ -177,9 +187,11 @@ public function testFormatValue()
177187

178188
$context = [
179189
'_symfony' => [
180-
'property_formatter' => [
181-
sprintf('%s::$name', ClassicDummy::class) => [
182-
'deserialize' => fn (string $v, array $c): string => strtoupper($v),
190+
'deserialize' => [
191+
'property_formatter' => [
192+
ClassicDummy::class => [
193+
'name' => fn (string $v, array $c): string => strtoupper($v),
194+
],
183195
],
184196
],
185197
],

0 commit comments

Comments
 (0)