Skip to content

Commit d76050d

Browse files
committed
handle csv serialization
1 parent 86f77f7 commit d76050d

30 files changed

+2160
-119
lines changed

src/Symfony/Component/SerDes/Internal/Deserialize/Deserializer.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ final public function deserialize(mixed $data, Type|UnionType $type, array $cont
172172
}
173173

174174
if ($type->isObject()) {
175-
try {
176-
$className = $type->className();
177-
} catch (LogicException) {
175+
if (!$type->hasClass()) {
178176
$object = new \stdClass();
179177
foreach ($this->deserializeMixed($data, $type, $context) as $property => $value) {
180178
$object->{$property} = $value;
@@ -183,6 +181,7 @@ final public function deserialize(mixed $data, Type|UnionType $type, array $cont
183181
return $object;
184182
}
185183

184+
$className = $type->className();
186185
$objectProperties = $this->deserializeObjectProperties($data, $type, $context);
187186

188187
if (null === $objectProperties) {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\SerDes\Internal\Serialize\Node;
13+
14+
use Symfony\Component\SerDes\Internal\Serialize\Compiler;
15+
use Symfony\Component\SerDes\Internal\Serialize\NodeInterface;
16+
use Symfony\Component\SerDes\Internal\Serialize\Optimizer;
17+
18+
/**
19+
* @author Mathias Arlaud <[email protected]>
20+
*
21+
* @internal
22+
*/
23+
final class ArrayNode implements NodeInterface
24+
{
25+
/**
26+
* @param array<int|string, NodeInterface> $elements
27+
*/
28+
public function __construct(
29+
public readonly array $elements,
30+
) {
31+
}
32+
33+
public function compile(Compiler $compiler): void
34+
{
35+
$compiler->raw('[');
36+
37+
$first = true;
38+
$associative = !array_is_list($this->elements);
39+
40+
foreach ($this->elements as $key => $value) {
41+
if (!$first) {
42+
$compiler->raw(', ');
43+
}
44+
45+
$first = false;
46+
47+
if ($associative) {
48+
$compiler->compile(new ScalarNode($key))->raw(' => ');
49+
}
50+
51+
$compiler->compile($value);
52+
}
53+
54+
$compiler->raw(']');
55+
}
56+
57+
public function optimize(Optimizer $optimizer): static
58+
{
59+
return new self($optimizer->optimize($this->elements));
60+
}
61+
}

src/Symfony/Component/SerDes/Internal/Serialize/Node/BinaryNode.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ final class BinaryNode implements NodeInterface
2727
'&&',
2828
'||',
2929
'===',
30+
'!==',
3031
'instanceof',
3132
'??',
33+
'+',
34+
'-',
3235
];
3336

3437
public function __construct(
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\SerDes\Internal\Serialize\Node;
13+
14+
use Symfony\Component\SerDes\Internal\Serialize\Compiler;
15+
use Symfony\Component\SerDes\Internal\Serialize\NodeInterface;
16+
use Symfony\Component\SerDes\Internal\Serialize\Optimizer;
17+
18+
/**
19+
* @author Mathias Arlaud <[email protected]>
20+
*
21+
* @internal
22+
*/
23+
final class CastNode implements NodeInterface
24+
{
25+
public function __construct(
26+
public readonly string $type,
27+
public readonly NodeInterface $node,
28+
) {
29+
}
30+
31+
public function compile(Compiler $compiler): void
32+
{
33+
$compiler->raw(sprintf('(%s) (%s)', $this->type, $compiler->subcompile($this->node)));
34+
}
35+
36+
public function optimize(Optimizer $optimizer): static
37+
{
38+
return new self($this->type, $optimizer->optimize($this->node));
39+
}
40+
}

src/Symfony/Component/SerDes/Internal/Serialize/Node/ClosureNode.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,26 @@ final class ClosureNode implements NodeInterface
2424
{
2525
/**
2626
* @param list<NodeInterface> $body
27+
* @param list<VariableNode> $uses
2728
*/
2829
public function __construct(
2930
public readonly ArgumentsNode $arguments,
3031
public readonly ?string $returnType,
3132
public readonly bool $static,
3233
public readonly array $body,
34+
public readonly array $uses = [],
3335
) {
3436
}
3537

3638
public function compile(Compiler $compiler): void
3739
{
3840
$staticSource = $this->static ? 'static ' : '';
3941
$argumentsSource = $compiler->subcompile($this->arguments);
42+
$usesSource = [] !== $this->uses ? sprintf(' use (%s)', implode(', ', array_map(fn (NodeInterface $v): string => $compiler->subcompile($v), $this->uses))) : '';
4043
$returnTypeSource = $this->returnType ? ': '.$this->returnType : '';
4144

4245
$compiler
43-
->raw(sprintf('%sfunction (%s)%s {', $staticSource, $argumentsSource, $returnTypeSource).\PHP_EOL)
46+
->raw(sprintf('%sfunction (%s)%s%s {', $staticSource, $argumentsSource, $usesSource, $returnTypeSource).\PHP_EOL)
4447
->indent();
4548

4649
foreach ($this->body as $bodyNode) {
@@ -59,6 +62,7 @@ public function optimize(Optimizer $optimizer): static
5962
$this->returnType,
6063
$this->static,
6164
$optimizer->optimize($this->body),
65+
$optimizer->optimize($this->uses),
6266
);
6367
}
6468
}

src/Symfony/Component/SerDes/Internal/Serialize/Node/ForEachNode.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,28 @@ public function __construct(
3535

3636
public function compile(Compiler $compiler): void
3737
{
38+
$valueName = $this->valueName;
39+
$byReference = false;
40+
41+
if (str_starts_with($this->valueName, '&')) {
42+
$byReference = true;
43+
$valueName = substr($valueName, 1);
44+
}
45+
3846
if (null === $this->keyName) {
3947
$compiler->line(sprintf(
40-
'foreach (%s as %s) {',
48+
'foreach (%s as %s%s) {',
4149
$compiler->subcompile($this->collection),
42-
$compiler->subcompile(new VariableNode($this->valueName)),
50+
$byReference ? '&' : '',
51+
$compiler->subcompile(new VariableNode($valueName)),
4352
));
4453
} else {
4554
$compiler->line(sprintf(
46-
'foreach (%s as %s => %s) {',
55+
'foreach (%s as %s => %s%s) {',
4756
$compiler->subcompile($this->collection),
4857
$compiler->subcompile(new VariableNode($this->keyName)),
49-
$compiler->subcompile(new VariableNode($this->valueName)),
58+
$byReference ? '&' : '',
59+
$compiler->subcompile(new VariableNode($valueName)),
5060
));
5161
}
5262

src/Symfony/Component/SerDes/Internal/Serialize/Node/FunctionNode.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,23 @@
2323
final class FunctionNode implements NodeInterface
2424
{
2525
/**
26-
* @param list<NodeInterface> $parameters
26+
* @param list<NodeInterface> $arguments
2727
*/
2828
public function __construct(
2929
public readonly string $name,
30-
public readonly array $parameters,
30+
public readonly array $arguments,
3131
) {
3232
}
3333

3434
public function compile(Compiler $compiler): void
3535
{
36-
$parameters = implode(', ', array_map(fn (NodeInterface $v): string => $compiler->subcompile($v), $this->parameters));
36+
$arguments = implode(', ', array_map(fn (NodeInterface $v): string => $compiler->subcompile($v), $this->arguments));
3737

38-
$compiler->raw(sprintf('%s(%s)', $this->name, $parameters));
38+
$compiler->raw(sprintf('%s(%s)', $this->name, $arguments));
3939
}
4040

4141
public function optimize(Optimizer $optimizer): static
4242
{
43-
return new self($this->name, $optimizer->optimize($this->parameters));
43+
return new self($this->name, $optimizer->optimize($this->arguments));
4444
}
4545
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\SerDes\Internal\Serialize\Node;
13+
14+
use Symfony\Component\SerDes\Internal\Serialize\Compiler;
15+
use Symfony\Component\SerDes\Internal\Serialize\NodeInterface;
16+
use Symfony\Component\SerDes\Internal\Serialize\Optimizer;
17+
18+
/**
19+
* @author Mathias Arlaud <[email protected]>
20+
*
21+
* @internal
22+
*/
23+
final class MethodNode implements NodeInterface
24+
{
25+
/**
26+
* @param list<NodeInterface> $arguments
27+
*/
28+
public function __construct(
29+
public readonly NodeInterface $object,
30+
public readonly string $method,
31+
public readonly array $arguments,
32+
) {
33+
}
34+
35+
public function compile(Compiler $compiler): void
36+
{
37+
$arguments = implode(', ', array_map(fn (NodeInterface $v): string => $compiler->subcompile($v), $this->arguments));
38+
39+
$compiler
40+
->compile($this->object)
41+
->raw(sprintf('->%s(%s)', $this->method, $arguments));
42+
}
43+
44+
public function optimize(Optimizer $optimizer): static
45+
{
46+
return new self($optimizer->optimize($this->object), $this->method, $optimizer->optimize($this->arguments));
47+
}
48+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\SerDes\Internal\Serialize\Node;
13+
14+
use Symfony\Component\SerDes\Internal\Serialize\Compiler;
15+
use Symfony\Component\SerDes\Internal\Serialize\NodeInterface;
16+
use Symfony\Component\SerDes\Internal\Serialize\Optimizer;
17+
18+
/**
19+
* @author Mathias Arlaud <[email protected]>
20+
*
21+
* @internal
22+
*/
23+
final class NewNode implements NodeInterface
24+
{
25+
/**
26+
* @param list<NodeInterface> $arguments
27+
*/
28+
public function __construct(
29+
public readonly string $class,
30+
public readonly array $arguments,
31+
) {
32+
}
33+
34+
public function compile(Compiler $compiler): void
35+
{
36+
$arguments = implode(', ', array_map(fn (NodeInterface $v): string => $compiler->subcompile($v), $this->arguments));
37+
38+
$compiler->raw(sprintf('new %s(%s)', $this->class, $arguments));
39+
}
40+
41+
public function optimize(Optimizer $optimizer): static
42+
{
43+
return new self($this->class, $optimizer->optimize($this->arguments));
44+
}
45+
}

src/Symfony/Component/SerDes/Internal/Serialize/Node/TernaryConditionNode.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ public function __construct(
3232
public function compile(Compiler $compiler): void
3333
{
3434
$compiler
35+
->raw('(')
3536
->compile($this->condition)
3637
->raw(' ? ')
3738
->compile($this->onTrue)
3839
->raw(' : ')
39-
->compile($this->onFalse);
40+
->compile($this->onFalse)
41+
->raw(')');
4042
}
4143

4244
public function optimize(Optimizer $optimizer): static
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\SerDes\Internal\Serialize\Node;
13+
14+
use Symfony\Component\SerDes\Internal\Serialize\Compiler;
15+
use Symfony\Component\SerDes\Internal\Serialize\NodeInterface;
16+
use Symfony\Component\SerDes\Internal\Serialize\Optimizer;
17+
18+
/**
19+
* @author Mathias Arlaud <[email protected]>
20+
*
21+
* @internal
22+
*/
23+
final class ThrowNode implements NodeInterface
24+
{
25+
public function __construct(
26+
public readonly NodeInterface $node,
27+
) {
28+
}
29+
30+
public function compile(Compiler $compiler): void
31+
{
32+
$compiler->raw(sprintf('throw %s', $compiler->subcompile($this->node)));
33+
}
34+
35+
public function optimize(Optimizer $optimizer): static
36+
{
37+
return new self($optimizer->optimize($this->node));
38+
}
39+
}

0 commit comments

Comments
 (0)