Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

Commitf8da717

Browse files
[DependencyInjection] Don't skip classes with private constructor when autodiscovering
1 parent6f4f04b commitf8da717

File tree

4 files changed

+61
-41
lines changed

4 files changed

+61
-41
lines changed

‎src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Make`#[AsTaggedItem]` repeatable
88
* Support`@>` as a shorthand for`!service_closure` in yaml files
9+
* Don't skip classes with private constructor when autodiscovering
910

1011
7.2
1112
---

‎src/Symfony/Component/DependencyInjection/Loader/FileLoader.php

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -188,41 +188,48 @@ public function registerClasses(Definition $prototype, string $namespace, string
188188
}
189189
}
190190

191-
if (interface_exists($class,false)) {
192-
$this->interfaces[] =$class;
193-
}else {
194-
$this->setDefinition($class,$definition =$getPrototype());
195-
if (null !==$errorMessage) {
196-
$definition->addError($errorMessage);
197-
198-
continue;
191+
$r =null ===$errorMessage ?$this->container->getReflectionClass($class) :null;
192+
if ($r?->isAbstract() ||$r?->isInterface()) {
193+
if ($r->isInterface()) {
194+
$this->interfaces[] =$class;
199195
}
200-
$definition->setClass($class);
201-
202-
$interfaces = [];
203-
foreach (class_implements($class,false)as$interface) {
204-
$this->singlyImplemented[$interface] = ($this->singlyImplemented[$interface] ??$class) !==$class ?false :$class;
205-
$interfaces[] =$interface;
196+
if ($autoconfigureAttributes) {
197+
$autoconfigureAttributes->processClass($this->container,$r);
206198
}
199+
continue;
200+
}
207201

208-
if (!$autoconfigureAttributes) {
209-
continue;
202+
$this->setDefinition($class,$definition =$getPrototype());
203+
if (null !==$errorMessage) {
204+
$definition->addError($errorMessage);
205+
206+
continue;
207+
}
208+
$definition->setClass($class);
209+
210+
$interfaces = [];
211+
foreach (class_implements($class,false)as$interface) {
212+
$this->singlyImplemented[$interface] = ($this->singlyImplemented[$interface] ??$class) !==$class ?false :$class;
213+
$interfaces[] =$interface;
214+
}
215+
216+
if (!$autoconfigureAttributes) {
217+
continue;
218+
}
219+
$r =$this->container->getReflectionClass($class);
220+
$defaultAlias =1 ===\count($interfaces) ?$interfaces[0] :null;
221+
foreach ($r->getAttributes(AsAlias::class)as$attr) {
222+
/** @var AsAlias $attribute */
223+
$attribute =$attr->newInstance();
224+
$alias =$attribute->id ??$defaultAlias;
225+
$public =$attribute->public;
226+
if (null ===$alias) {
227+
thrownewLogicException(\sprintf('Alias cannot be automatically determined for class "%s". If you have used the #[AsAlias] attribute with a class implementing multiple interfaces, add the interface you want to alias to the first parameter of #[AsAlias].',$class));
210228
}
211-
$r =$this->container->getReflectionClass($class);
212-
$defaultAlias =1 ===\count($interfaces) ?$interfaces[0] :null;
213-
foreach ($r->getAttributes(AsAlias::class)as$attr) {
214-
/** @var AsAlias $attribute */
215-
$attribute =$attr->newInstance();
216-
$alias =$attribute->id ??$defaultAlias;
217-
$public =$attribute->public;
218-
if (null ===$alias) {
219-
thrownewLogicException(\sprintf('Alias cannot be automatically determined for class "%s". If you have used the #[AsAlias] attribute with a class implementing multiple interfaces, add the interface you want to alias to the first parameter of #[AsAlias].',$class));
220-
}
221-
if (isset($this->aliases[$alias])) {
222-
thrownewLogicException(\sprintf('The "%s" alias has already been defined with the #[AsAlias] attribute in "%s".',$alias,$this->aliases[$alias]));
223-
}
224-
$this->aliases[$alias] =newAlias($class,$public);
229+
if (isset($this->aliases[$alias])) {
230+
thrownewLogicException(\sprintf('The "%s" alias has already been defined with the #[AsAlias] attribute in "%s".',$alias,$this->aliases[$alias]));
225231
}
232+
$this->aliases[$alias] =newAlias($class,$public);
226233
}
227234
}
228235

@@ -356,13 +363,9 @@ private function findClasses(string $namespace, string $pattern, array $excludeP
356363
thrownewInvalidArgumentException(\sprintf('Expected to find class "%s" in file "%s" while importing services from resource "%s", but it was not found! Check the namespace prefix used with the resource.',$class,$path,$pattern));
357364
}
358365

359-
if ($r->isInstantiable() ||$r->isInterface()) {
366+
if (!$r->isTrait()) {
360367
$classes[$class] =null;
361368
}
362-
363-
if ($autoconfigureAttributes && !$r->isInstantiable()) {
364-
$autoconfigureAttributes->processClass($this->container,$r);
365-
}
366369
}
367370

368371
// track only for new & removed files

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/StaticConstructor/PrototypeStaticConstructor.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
class PrototypeStaticConstructorimplements PrototypeStaticConstructorInterface
66
{
7+
privatefunction__construct()
8+
{
9+
}
10+
711
publicstaticfunctioncreate():static
812
{
913
returnnewself();

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
useSymfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\AnotherSub;
3434
useSymfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\AnotherSub\DeeperBaz;
3535
useSymfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Baz;
36+
useSymfony\Component\DependencyInjection\Tests\Fixtures\Prototype\StaticConstructor\PrototypeStaticConstructor;
3637
useSymfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar;
3738
useSymfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\BarInterface;
3839
useSymfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\AliasBarInterface;
@@ -380,11 +381,11 @@ public static function provideResourcesWithAsAliasAttributes(): iterable
380381
*/
381382
publicfunctiontestRegisterClassesWithDuplicatedAsAlias(string$resource,string$expectedExceptionMessage)
382383
{
383-
$this->expectException(LogicException::class);
384-
$this->expectExceptionMessage($expectedExceptionMessage);
385-
386384
$container =newContainerBuilder();
387385
$loader =newTestFileLoader($container,newFileLocator(self::$fixturesPath.'/Fixtures'));
386+
387+
$this->expectException(LogicException::class);
388+
$this->expectExceptionMessage($expectedExceptionMessage);
388389
$loader->registerClasses(
389390
(newDefinition())->setAutoconfigured(true),
390391
'Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\\',
@@ -400,17 +401,28 @@ public static function provideResourcesWithDuplicatedAsAliasAttributes(): iterab
400401

401402
publicfunctiontestRegisterClassesWithAsAliasAndImplementingMultipleInterfaces()
402403
{
403-
$this->expectException(LogicException::class);
404-
$this->expectExceptionMessage('Alias cannot be automatically determined for class "Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\WithAsAliasMultipleInterface". If you have used the #[AsAlias] attribute with a class implementing multiple interfaces, add the interface you want to alias to the first parameter of #[AsAlias].');
405-
406404
$container =newContainerBuilder();
407405
$loader =newTestFileLoader($container,newFileLocator(self::$fixturesPath.'/Fixtures'));
406+
407+
$this->expectException(LogicException::class);
408+
$this->expectExceptionMessage('Alias cannot be automatically determined for class "Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\WithAsAliasMultipleInterface". If you have used the #[AsAlias] attribute with a class implementing multiple interfaces, add the interface you want to alias to the first parameter of #[AsAlias].');
408409
$loader->registerClasses(
409410
(newDefinition())->setAutoconfigured(true),
410411
'Symfony\Component\DependencyInjection\Tests\Fixtures\PrototypeAsAlias\\',
411412
'PrototypeAsAlias/{WithAsAliasMultipleInterface,AliasBarInterface,AliasFooInterface}.php'
412413
);
413414
}
415+
416+
publicfunctiontestRegisterClassesWithStaticConstructor()
417+
{
418+
$container =newContainerBuilder();
419+
$loader =newTestFileLoader($container,newFileLocator(self::$fixturesPath.'/Fixtures'));
420+
421+
$prototype = (newDefinition())->setAutoconfigured(true);
422+
$loader->registerClasses($prototype,'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\StaticConstructor\\','Prototype/StaticConstructor');
423+
424+
$this->assertTrue($container->has(PrototypeStaticConstructor::class));
425+
}
414426
}
415427

416428
class TestFileLoaderextends FileLoader

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp