2121use Symfony \Component \DependencyInjection \ContainerBuilder ;
2222use Symfony \Component \DependencyInjection \Definition ;
2323use Symfony \Component \DependencyInjection \Exception \InvalidArgumentException ;
24+ use Symfony \Contracts \Service \Attribute \Autoconfigure ;
2425
2526/**
2627 * FileLoader is the abstract class used by all built-in loaders that are file based.
@@ -96,7 +97,7 @@ public function registerClasses(Definition $prototype, string $namespace, string
9697 throw new InvalidArgumentException (sprintf ('Namespace is not a valid PSR-4 prefix: "%s". ' , $ namespace ));
9798 }
9899
99- $ classes = $ this ->findClasses ($ namespace , $ resource , (array ) $ exclude );
100+ $ classes = $ this ->findClasses ($ namespace , $ resource , (array ) $ exclude, $ prototype -> isAutoconfigured () );
100101 // prepare for deep cloning
101102 $ serializedPrototype = serialize ($ prototype );
102103
@@ -149,7 +150,7 @@ protected function setDefinition(string $id, Definition $definition)
149150 }
150151 }
151152
152- private function findClasses (string $ namespace , string $ pattern , array $ excludePatterns ): array
153+ private function findClasses (string $ namespace , string $ pattern , array $ excludePatterns, bool $ autoconfigure ): array
153154 {
154155 $ parameterBag = $ this ->container ->getParameterBag ();
155156
@@ -167,6 +168,13 @@ private function findClasses(string $namespace, string $pattern, array $excludeP
167168 }
168169 }
169170
171+ if (80000 <= \PHP_VERSION_ID && $ autoconfigure ) {
172+ $ parseDefinition = new \ReflectionMethod (YamlFileLoader::class, 'parseDefinition ' );
173+ $ parseDefinition ->setAccessible (true );
174+ $ yamlLoader = $ parseDefinition ->getDeclaringClass ()->newInstanceWithoutConstructor ();
175+ $ yamlLoader ->isLoadingInstanceof = true ;
176+ }
177+
170178 $ pattern = $ parameterBag ->unescapeValue ($ parameterBag ->resolveValue ($ pattern ));
171179 $ classes = [];
172180 $ extRegexp = '/ \\.php$/ ' ;
@@ -207,6 +215,17 @@ private function findClasses(string $namespace, string $pattern, array $excludeP
207215 if ($ r ->isInstantiable () || $ r ->isInterface ()) {
208216 $ classes [$ class ] = null ;
209217 }
218+
219+ if (80000 > \PHP_VERSION_ID || !$ autoconfigure ) {
220+ continue ;
221+ }
222+
223+ foreach ($ r ->getAttributes (Autoconfigure::class, \ReflectionAttribute::IS_INSTANCEOF ) as $ attribute ) {
224+ if (!class_exists (Autoconfigure::class)) {
225+ throw new \LogicException (sprintf ('You cannot use the "%s" attribute unless Symfony Contracts 2.4+ are installed. Try running "composer require symfony/service-contracts:^2.4". ' , Autoconfigure::class));
226+ }
227+ $ parseDefinition ->invoke ($ yamlLoader , $ class , [$ this ->container ->registerForAutoconfiguration ($ class )] + (array ) $ attribute ->getInstance (), $ r ->getFileName (), [], true );
228+ }
210229 }
211230
212231 // track only for new & removed files
0 commit comments