21
21
use Symfony \Component \DependencyInjection \ContainerBuilder ;
22
22
use Symfony \Component \DependencyInjection \Definition ;
23
23
use Symfony \Component \DependencyInjection \Exception \InvalidArgumentException ;
24
+ use Symfony \Contracts \Service \Attribute \Autoconfigure ;
24
25
25
26
/**
26
27
* 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
96
97
throw new InvalidArgumentException (sprintf ('Namespace is not a valid PSR-4 prefix: "%s". ' , $ namespace ));
97
98
}
98
99
99
- $ classes = $ this ->findClasses ($ namespace , $ resource , (array ) $ exclude );
100
+ $ classes = $ this ->findClasses ($ namespace , $ resource , (array ) $ exclude, $ prototype -> isAutoconfigured () );
100
101
// prepare for deep cloning
101
102
$ serializedPrototype = serialize ($ prototype );
102
103
@@ -149,7 +150,7 @@ protected function setDefinition(string $id, Definition $definition)
149
150
}
150
151
}
151
152
152
- private function findClasses (string $ namespace , string $ pattern , array $ excludePatterns ): array
153
+ private function findClasses (string $ namespace , string $ pattern , array $ excludePatterns, bool $ autoconfigure ): array
153
154
{
154
155
$ parameterBag = $ this ->container ->getParameterBag ();
155
156
@@ -167,6 +168,13 @@ private function findClasses(string $namespace, string $pattern, array $excludeP
167
168
}
168
169
}
169
170
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
+
170
178
$ pattern = $ parameterBag ->unescapeValue ($ parameterBag ->resolveValue ($ pattern ));
171
179
$ classes = [];
172
180
$ extRegexp = '/ \\.php$/ ' ;
@@ -207,6 +215,17 @@ private function findClasses(string $namespace, string $pattern, array $excludeP
207
215
if ($ r ->isInstantiable () || $ r ->isInterface ()) {
208
216
$ classes [$ class ] = null ;
209
217
}
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
+ }
210
229
}
211
230
212
231
// track only for new & removed files
0 commit comments