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 bb4eb0d

Browse filesBrowse files
[DependencyInjection] Add support of PHP enumerations
1 parent ffb0d2d commit bb4eb0d
Copy full SHA for bb4eb0d

17 files changed

+213
-1
lines changed

‎src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ private function addNewInstance(Definition $definition, string $return = '', str
11011101
// If the class is a string we can optimize away
11021102
if (0 === strpos($class, "'") && false === strpos($class, '$')) {
11031103
if ("''" === $class) {
1104-
throw new RuntimeException(sprintf('Cannot dump definition: %s service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id ? 'The "'.$id.'"' : 'inline'));
1104+
throw new RuntimeException(sprintf('Cannot dump definition: "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id ? 'The "'.$id.'"' : 'inline'));
11051105
}
11061106

11071107
return $return.sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : '').$tail;
@@ -1812,6 +1812,8 @@ private function dumpValue($value, bool $interpolate = true): string
18121812

18131813
return $code;
18141814
}
1815+
} elseif ($value instanceof \UnitEnum) {
1816+
return sprintf('\%s::%s', \get_class($value), $value->name);
18151817
} elseif (\is_object($value) || \is_resource($value)) {
18161818
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
18171819
}

‎src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ private function convertParameters(array $parameters, string $type, \DOMElement
313313
$element->setAttribute('type', 'binary');
314314
$text = $this->document->createTextNode(self::phpToXml(base64_encode($value)));
315315
$element->appendChild($text);
316+
} elseif ($value instanceof \UnitEnum) {
317+
$element->setAttribute('type', 'constant');
318+
$element->appendChild($this->document->createTextNode(self::phpToXml($value)));
316319
} else {
317320
if (\in_array($value, ['null', 'true', 'false'], true)) {
318321
$element->setAttribute('type', 'string');
@@ -366,6 +369,8 @@ public static function phpToXml($value): string
366369
return 'false';
367370
case $value instanceof Parameter:
368371
return '%'.$value.'%';
372+
case $value instanceof \UnitEnum:
373+
return sprintf('%s::%s', \get_class($value), $value->name);
369374
case \is_object($value) || \is_resource($value):
370375
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
371376
default:

‎src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ private function dumpValue($value)
286286
return $this->getExpressionCall((string) $value);
287287
} elseif ($value instanceof Definition) {
288288
return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']);
289+
} elseif ($value instanceof \UnitEnum) {
290+
return new TaggedValue('php/const', sprintf('%s::%s', \get_class($value), $value->name));
289291
} elseif (\is_object($value) || \is_resource($value)) {
290292
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
291293
}

‎src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
4141
use Symfony\Component\DependencyInjection\Tests\Compiler\Wither;
4242
use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition;
43+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
44+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
4345
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
4446
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
4547
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
@@ -1208,6 +1210,29 @@ public function testDumpHandlesObjectClassNames()
12081210
$this->assertInstanceOf(\stdClass::class, $container->get('bar'));
12091211
}
12101212

1213+
/**
1214+
* @requires PHP 8.1
1215+
*/
1216+
public function testDumpHandlesEnumeration()
1217+
{
1218+
$container = new ContainerBuilder();
1219+
$container
1220+
->register('foo', FooClassWithEnumAttribute::class)
1221+
->setPublic(true)
1222+
->addArgument(FooUnitEnum::BAR);
1223+
1224+
$container->compile();
1225+
1226+
$dumper = new PhpDumper($container);
1227+
eval('?>'.$dumper->dump([
1228+
'class' => 'Symfony_DI_PhpDumper_Test_Enumeration',
1229+
]));
1230+
1231+
$container = new \Symfony_DI_PhpDumper_Test_Enumeration();
1232+
1233+
$this->assertSame(FooUnitEnum::BAR, $container->get('foo')->getBar());
1234+
}
1235+
12111236
public function testUninitializedSyntheticReference()
12121237
{
12131238
$container = new ContainerBuilder();

‎src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Dumper/XmlDumperTest.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
2222
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
2323
use Symfony\Component\DependencyInjection\Reference;
24+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
25+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
2426

2527
class XmlDumperTest extends TestCase
2628
{
@@ -249,4 +251,21 @@ public function testDumpAbstractServices()
249251

250252
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump());
251253
}
254+
255+
/**
256+
* @requires PHP 8.1
257+
*/
258+
public function testDumpHandlesEnumeration()
259+
{
260+
$container = new ContainerBuilder();
261+
$container
262+
->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class)
263+
->setPublic(true)
264+
->addArgument(FooUnitEnum::BAR);
265+
266+
$container->compile();
267+
$dumper = new XmlDumper($container);
268+
269+
$this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_with_enumeration.xml'), $dumper->dump());
270+
}
252271
}

‎src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Dumper/YamlDumperTest.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
2323
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
2424
use Symfony\Component\DependencyInjection\Reference;
25+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
26+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
2527
use Symfony\Component\Yaml\Parser;
2628
use Symfony\Component\Yaml\Yaml;
2729

@@ -129,6 +131,23 @@ public function testServiceClosure()
129131
$this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_with_service_closure.yml', $dumper->dump());
130132
}
131133

134+
/**
135+
* @requires PHP 8.1
136+
*/
137+
public function testDumpHandlesEnumeration()
138+
{
139+
$container = new ContainerBuilder();
140+
$container
141+
->register(FooClassWithEnumAttribute::class, FooClassWithEnumAttribute::class)
142+
->setPublic(true)
143+
->addArgument(FooUnitEnum::BAR);
144+
145+
$container->compile();
146+
$dumper = new YamlDumper($container);
147+
148+
$this->assertEquals(file_get_contents(self::$fixturesPath.'/yaml/services_with_enumeration.yml'), $dumper->dump());
149+
}
150+
132151
private function assertEqualYamlStructure(string $expected, string $yaml, string $message = '')
133152
{
134153
$parser = new Parser();
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
class FooClassWithEnumAttribute
6+
{
7+
private FooUnitEnum $bar;
8+
9+
public function __construct(FooUnitEnum $bar)
10+
{
11+
$this->bar = $bar;
12+
}
13+
14+
public function getBar(): FooUnitEnum
15+
{
16+
return $this->bar;
17+
}
18+
}
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
enum FooUnitEnum
6+
{
7+
case BAR;
8+
}
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
5+
<service id="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" class="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" public="true">
6+
<argument type="constant">Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAR</argument>
7+
</service>
8+
</services>
9+
</container>
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service id="service_container" class="Symfony\Component\DependencyInjection\ContainerInterface" public="true" synthetic="true"/>
5+
<service id="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" class="Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute" public="true">
6+
<argument type="constant">Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ</argument>
7+
</service>
8+
</services>
9+
</container>
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
services:
3+
service_container:
4+
class: Symfony\Component\DependencyInjection\ContainerInterface
5+
public: true
6+
synthetic: true
7+
Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute:
8+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute
9+
public: true
10+
arguments: [!php/const 'Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAR']
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
services:
3+
service_container:
4+
class: Symfony\Component\DependencyInjection\ContainerInterface
5+
public: true
6+
synthetic: true
7+
Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute:
8+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute
9+
public: true
10+
arguments: [!php/const 'Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ']

‎src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar;
3838
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface;
3939
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
40+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
41+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
4042
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
4143
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
4244
use Symfony\Component\ExpressionLanguage\Expression;
@@ -827,6 +829,32 @@ public function testInstanceof()
827829
$this->assertSame(['foo' => [[]], 'bar' => [[]]], $definition->getTags());
828830
}
829831

832+
/**
833+
* @requires PHP 8.1
834+
*/
835+
public function testEnumeration()
836+
{
837+
$container = new ContainerBuilder();
838+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
839+
$loader->load('services_with_enumeration.xml');
840+
$container->compile();
841+
842+
$definition = $container->getDefinition(FooClassWithEnumAttribute::class);
843+
$this->assertSame([FooUnitEnum::BAR], $definition->getArguments());
844+
}
845+
846+
/**
847+
* @requires PHP 8.1
848+
*/
849+
public function testInvalidEnumeration()
850+
{
851+
$container = new ContainerBuilder();
852+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
853+
854+
$this->expectException(\Error::class);
855+
$loader->load('services_with_invalid_enumeration.xml');
856+
}
857+
830858
public function testInstanceOfAndChildDefinitionNotAllowed()
831859
{
832860
$this->expectException(InvalidArgumentException::class);

‎src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar;
3838
use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface;
3939
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
40+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooClassWithEnumAttribute;
41+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum;
4042
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
4143
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
4244
use Symfony\Component\ExpressionLanguage\Expression;
@@ -909,6 +911,33 @@ public function testDefaultValueOfTagged()
909911
$this->assertNull($iteratorArgument->getIndexAttribute());
910912
}
911913

914+
/**
915+
* @requires PHP 8.1
916+
*/
917+
public function testEnumeration()
918+
{
919+
$container = new ContainerBuilder();
920+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
921+
$loader->load('services_with_enumeration.yml');
922+
$container->compile();
923+
924+
$definition = $container->getDefinition(FooClassWithEnumAttribute::class);
925+
$this->assertSame([FooUnitEnum::BAR], $definition->getArguments());
926+
}
927+
928+
/**
929+
* @requires PHP 8.1
930+
*/
931+
public function testInvalidEnumeration()
932+
{
933+
$container = new ContainerBuilder();
934+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
935+
936+
$this->expectException(InvalidArgumentException::class);
937+
$this->expectExceptionMessage('The constant "Symfony\Component\DependencyInjection\Tests\Fixtures\FooUnitEnum::BAZ" is not defined');
938+
$loader->load('services_with_invalid_enumeration.yml');
939+
}
940+
912941
public function testReturnsClone()
913942
{
914943
$container = new ContainerBuilder();

‎src/Symfony/Component/Yaml/Inline.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Inline.php
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ public static function dump($value, int $flags = 0): string
127127
return self::dumpNull($flags);
128128
case $value instanceof \DateTimeInterface:
129129
return $value->format('c');
130+
case $value instanceof \UnitEnum:
131+
return sprintf("!php/const '%s::%s'", \get_class($value), $value->name);
130132
case \is_object($value):
131133
if ($value instanceof TaggedValue) {
132134
return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags);
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Symfony\Component\Yaml\Tests\Fixtures;
4+
5+
enum FooUnitEnum
6+
{
7+
case BAR;
8+
}

‎src/Symfony/Component/Yaml/Tests/InlineTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Yaml/Tests/InlineTest.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Yaml\Exception\ParseException;
1616
use Symfony\Component\Yaml\Inline;
1717
use Symfony\Component\Yaml\Tag\TaggedValue;
18+
use Symfony\Component\Yaml\Tests\Fixtures\FooUnitEnum;
1819
use Symfony\Component\Yaml\Yaml;
1920

2021
class InlineTest extends TestCase
@@ -577,6 +578,14 @@ public function testDumpDateTime($dateTime, $expected)
577578
$this->assertSame($expected, Inline::dump($dateTime));
578579
}
579580

581+
/**
582+
* @requires PHP 8.1
583+
*/
584+
public function testDumpUnitEnum()
585+
{
586+
$this->assertSame("!php/const 'Symfony\Component\Yaml\Tests\Fixtures\FooUnitEnum::BAR'", Inline::dump(FooUnitEnum::BAR));
587+
}
588+
580589
public function getDateTimeDumpTests()
581590
{
582591
$tests = [];

0 commit comments

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