Skip to content

Commit ca0912f

Browse files
committed
feature symfony#59254 [JsonEncoder] Remove chunk size definition (mtarld)
This PR was merged into the 7.3 branch. Discussion ---------- [JsonEncoder] Remove chunk size definition | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | | License | MIT Remove the `$forceEncodeChunks` boolean. This boolean was telling if the encoder should use `json_encode` or should yield as small strings as possible. It was set to `false` by default and not easily configurable yet. This configurable behavior has been removed. Instead, we use `json_encode` directly if **the value that does not contain any object**. Otherwise, it'll be split (see the diff in `src/Symfony/Component/JsonEncoder/Tests/Fixtures/encoder/object_in_object.php`) IMHO, this will fit most of the use cases, and remove a configuration complicated to understand. Commits ------- 8627499 [JsonEncoder] Remove chunk size definition
2 parents 0a9eb28 + 8627499 commit ca0912f

32 files changed

+20
-345
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/json_encoder.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
tagged_locator('json_encoder.normalizer'),
3333
service('json_encoder.encode.property_metadata_loader'),
3434
param('.json_encoder.encoders_dir'),
35-
false,
3635
])
3736
->set('json_encoder.decoder', JsonDecoder::class)
3837
->args([
@@ -113,7 +112,6 @@
113112
service('json_encoder.decode.property_metadata_loader'),
114113
param('.json_encoder.encoders_dir'),
115114
param('.json_encoder.decoders_dir'),
116-
false,
117115
service('logger')->ignoreOnInvalid(),
118116
])
119117
->tag('kernel.cache_warmer')

src/Symfony/Component/JsonEncoder/CacheWarmer/EncoderDecoderCacheWarmer.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ public function __construct(
4141
PropertyMetadataLoaderInterface $decodePropertyMetadataLoader,
4242
string $encodersDir,
4343
string $decodersDir,
44-
bool $forceEncodeChunks = false,
4544
private LoggerInterface $logger = new NullLogger(),
4645
) {
47-
$this->encoderGenerator = new EncoderGenerator($encodePropertyMetadataLoader, $encodersDir, $forceEncodeChunks);
46+
$this->encoderGenerator = new EncoderGenerator($encodePropertyMetadataLoader, $encodersDir);
4847
$this->decoderGenerator = new DecoderGenerator($decodePropertyMetadataLoader, $decodersDir);
4948
}
5049

src/Symfony/Component/JsonEncoder/DataModel/Encode/ObjectNode.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ public function __construct(
3030
private DataAccessorInterface $accessor,
3131
private ObjectType $type,
3232
private array $properties,
33-
private bool $transformed,
3433
) {
3534
}
3635

@@ -51,9 +50,4 @@ public function getProperties(): array
5150
{
5251
return $this->properties;
5352
}
54-
55-
public function isTransformed(): bool
56-
{
57-
return $this->transformed;
58-
}
5953
}

src/Symfony/Component/JsonEncoder/Encode/EncoderGenerator.php

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
use Symfony\Component\JsonEncoder\Exception\MaxDepthException;
3232
use Symfony\Component\JsonEncoder\Exception\RuntimeException;
3333
use Symfony\Component\JsonEncoder\Exception\UnsupportedException;
34-
use Symfony\Component\JsonEncoder\Mapping\PropertyMetadata;
3534
use Symfony\Component\JsonEncoder\Mapping\PropertyMetadataLoaderInterface;
3635
use Symfony\Component\TypeInfo\Type;
3736
use Symfony\Component\TypeInfo\Type\BackedEnumType;
@@ -57,13 +56,9 @@ final class EncoderGenerator
5756
private ?PrettyPrinter $phpPrinter = null;
5857
private ?Filesystem $fs = null;
5958

60-
/**
61-
* @param bool $forceEncodeChunks enforces chunking the JSON string even if a simple `json_encode` is enough
62-
*/
6359
public function __construct(
6460
private PropertyMetadataLoaderInterface $propertyMetadataLoader,
6561
private string $encodersDir,
66-
private bool $forceEncodeChunks,
6762
) {
6863
}
6964

@@ -79,7 +74,7 @@ public function generate(Type $type, array $options = []): string
7974
return $path;
8075
}
8176

82-
$this->phpAstBuilder ??= new PhpAstBuilder($this->forceEncodeChunks);
77+
$this->phpAstBuilder ??= new PhpAstBuilder();
8378
$this->phpOptimizer ??= new PhpOptimizer();
8479
$this->phpPrinter ??= new Standard(['phpVersion' => PhpVersion::fromComponents(8, 2)]);
8580
$this->fs ??= new Filesystem();
@@ -110,7 +105,7 @@ public function generate(Type $type, array $options = []): string
110105

111106
private function getPath(Type $type): string
112107
{
113-
return \sprintf('%s%s%s.json%s.php', $this->encodersDir, \DIRECTORY_SEPARATOR, hash('xxh128', (string) $type), $this->forceEncodeChunks ? '.stream' : '');
108+
return \sprintf('%s%s%s.json.php', $this->encodersDir, \DIRECTORY_SEPARATOR, hash('xxh128', (string) $type));
114109
}
115110

116111
/**
@@ -142,7 +137,6 @@ private function createDataModel(Type $type, DataAccessorInterface $accessor, ar
142137
if ($type instanceof ObjectType && !$type instanceof EnumType) {
143138
++$context['depth'];
144139

145-
$transformed = false;
146140
$className = $type->getClassName();
147141
$propertiesMetadata = $this->propertyMetadataLoader->load($className, $options, ['original_type' => $type] + $context);
148142

@@ -152,20 +146,12 @@ private function createDataModel(Type $type, DataAccessorInterface $accessor, ar
152146
throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
153147
}
154148

155-
if (\count($classReflection->getProperties()) !== \count($propertiesMetadata)
156-
|| array_values(array_map(fn (PropertyMetadata $m): string => $m->getName(), $propertiesMetadata)) !== array_keys($propertiesMetadata)
157-
) {
158-
$transformed = true;
159-
}
160-
161149
$propertiesNodes = [];
162150

163151
foreach ($propertiesMetadata as $encodedName => $propertyMetadata) {
164152
$propertyAccessor = new PropertyDataAccessor($accessor, $propertyMetadata->getName());
165153

166154
foreach ($propertyMetadata->getNormalizers() as $normalizer) {
167-
$transformed = true;
168-
169155
if (\is_string($normalizer)) {
170156
$normalizerServiceAccessor = new FunctionDataAccessor('get', [new ScalarDataAccessor($normalizer)], new VariableDataAccessor('normalizers'));
171157
$propertyAccessor = new FunctionDataAccessor('normalize', [$propertyAccessor, new VariableDataAccessor('options')], $normalizerServiceAccessor);
@@ -190,7 +176,7 @@ private function createDataModel(Type $type, DataAccessorInterface $accessor, ar
190176
$propertiesNodes[$encodedName] = $this->createDataModel($propertyMetadata->getType(), $propertyAccessor, $options, $context);
191177
}
192178

193-
return new ObjectNode($accessor, $type, $propertiesNodes, $transformed);
179+
return new ObjectNode($accessor, $type, $propertiesNodes);
194180
}
195181

196182
if ($type instanceof CollectionType) {

src/Symfony/Component/JsonEncoder/Encode/PhpAstBuilder.php

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ final class PhpAstBuilder
5959
{
6060
private BuilderFactory $builder;
6161

62-
public function __construct(
63-
private bool $forceEncodeChunks = false,
64-
) {
62+
public function __construct()
63+
{
6564
$this->builder = new BuilderFactory();
6665
}
6766

@@ -103,7 +102,7 @@ private function buildClosureStatements(DataModelNodeInterface $dataModelNode, a
103102
];
104103
}
105104

106-
if (!$this->forceEncodeChunks && $this->nodeOnlyNeedsEncode($dataModelNode)) {
105+
if ($this->nodeOnlyNeedsEncode($dataModelNode)) {
107106
return [
108107
new Expression(new Yield_($this->encodeValue($accessor))),
109108
];
@@ -276,21 +275,12 @@ private function nodeOnlyNeedsEncode(DataModelNodeInterface $node, int $nestingL
276275
return $this->nodeOnlyNeedsEncode($node->getItemNode(), $nestingLevel + 1);
277276
}
278277

279-
if ($node instanceof ObjectNode && !$node->isTransformed()) {
280-
foreach ($node->getProperties() as $property) {
281-
if (!$this->nodeOnlyNeedsEncode($property, $nestingLevel + 1)) {
282-
return false;
283-
}
284-
}
285-
286-
return true;
287-
}
288-
289278
if ($node instanceof ScalarNode) {
290279
$type = $node->getType();
291280

292281
// "null" will be written directly using the "null" string
293282
// "bool" will be written directly using the "true" or "false" string
283+
// but it must not prevent any json_encode if nested
294284
if ($type->isIdentifiedBy(TypeIdentifier::NULL) || $type->isIdentifiedBy(TypeIdentifier::BOOL)) {
295285
return $nestingLevel > 0;
296286
}

src/Symfony/Component/JsonEncoder/JsonEncoder.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,12 @@ final class JsonEncoder implements EncoderInterface
3737
{
3838
private EncoderGenerator $encoderGenerator;
3939

40-
/**
41-
* @param bool $forceEncodeChunks enforces chunking the JSON string even if a simple `json_encode` is enough
42-
*/
4340
public function __construct(
4441
private ContainerInterface $normalizers,
4542
PropertyMetadataLoaderInterface $propertyMetadataLoader,
4643
string $encodersDir,
47-
bool $forceEncodeChunks = false,
4844
) {
49-
$this->encoderGenerator = new EncoderGenerator($propertyMetadataLoader, $encodersDir, $forceEncodeChunks);
45+
$this->encoderGenerator = new EncoderGenerator($propertyMetadataLoader, $encodersDir);
5046
}
5147

5248
public function encode(mixed $data, Type $type, array $options = []): \Traversable&\Stringable
@@ -58,9 +54,8 @@ public function encode(mixed $data, Type $type, array $options = []): \Traversab
5854

5955
/**
6056
* @param array<string, NormalizerInterface> $normalizers
61-
* @param bool $forceEncodeChunks enforces chunking the JSON string even if a simple `json_encode` is enough
6257
*/
63-
public static function create(array $normalizers = [], ?string $encodersDir = null, bool $forceEncodeChunks = false): self
58+
public static function create(array $normalizers = [], ?string $encodersDir = null): self
6459
{
6560
$encodersDir ??= sys_get_temp_dir().'/json_encoder/encoder';
6661
$normalizers += [
@@ -97,6 +92,6 @@ public function get(string $id): NormalizerInterface
9792
$typeContextFactory,
9893
);
9994

100-
return new self($normalizersContainer, $propertyMetadataLoader, $encodersDir, $forceEncodeChunks);
95+
return new self($normalizersContainer, $propertyMetadataLoader, $encodersDir);
10196
}
10297
}

src/Symfony/Component/JsonEncoder/Tests/DataModel/Encode/CompositeNodeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function testSortNodesOnCreation()
4848
{
4949
$composite = new CompositeNode(new VariableDataAccessor('data'), [
5050
$scalar = new ScalarNode(new VariableDataAccessor('data'), Type::int()),
51-
$object = new ObjectNode(new VariableDataAccessor('data'), Type::object(self::class), [], false),
51+
$object = new ObjectNode(new VariableDataAccessor('data'), Type::object(self::class), []),
5252
$collection = new CollectionNode(new VariableDataAccessor('data'), Type::list(), new ScalarNode(new VariableDataAccessor('data'), Type::int())),
5353
]);
5454

src/Symfony/Component/JsonEncoder/Tests/Encode/EncoderGeneratorTest.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,12 @@ public function testGeneratedEncoder(string $fixture, Type $type)
6666
new TypeContextFactory(new StringTypeResolver()),
6767
);
6868

69-
$generator = new EncoderGenerator($propertyMetadataLoader, $this->encodersDir, forceEncodeChunks: false);
69+
$generator = new EncoderGenerator($propertyMetadataLoader, $this->encodersDir);
7070

7171
$this->assertStringEqualsFile(
7272
\sprintf('%s/Fixtures/encoder/%s.php', \dirname(__DIR__), $fixture),
7373
file_get_contents($generator->generate($type)),
7474
);
75-
76-
$generator = new EncoderGenerator($propertyMetadataLoader, $this->encodersDir, forceEncodeChunks: true);
77-
78-
$this->assertStringEqualsFile(
79-
\sprintf('%s/Fixtures/encoder/%s.stream.php', \dirname(__DIR__), $fixture),
80-
file_get_contents($generator->generate($type)),
81-
);
8275
}
8376

8477
/**
@@ -117,7 +110,7 @@ public static function generatedEncoderDataProvider(): iterable
117110

118111
public function testDoNotSupportIntersectionType()
119112
{
120-
$generator = new EncoderGenerator(new PropertyMetadataLoader(TypeResolver::create()), $this->encodersDir, false);
113+
$generator = new EncoderGenerator(new PropertyMetadataLoader(TypeResolver::create()), $this->encodersDir);
121114

122115
$this->expectException(UnsupportedException::class);
123116
$this->expectExceptionMessage('"Stringable&Traversable" type is not supported.');
@@ -127,7 +120,7 @@ public function testDoNotSupportIntersectionType()
127120

128121
public function testDoNotSupportEnumType()
129122
{
130-
$generator = new EncoderGenerator(new PropertyMetadataLoader(TypeResolver::create()), $this->encodersDir, false);
123+
$generator = new EncoderGenerator(new PropertyMetadataLoader(TypeResolver::create()), $this->encodersDir);
131124

132125
$this->expectException(UnsupportedException::class);
133126
$this->expectExceptionMessage(\sprintf('"%s" type is not supported.', DummyEnum::class));

src/Symfony/Component/JsonEncoder/Tests/Fixtures/encoder/backed_enum.stream.php

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/Symfony/Component/JsonEncoder/Tests/Fixtures/encoder/bool.stream.php

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)