comparison vendor/symfony/dependency-injection/Loader/YamlFileLoader.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents 1fec387a4317
children af1871eacc83
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
18 use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; 18 use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
19 use Symfony\Component\DependencyInjection\ChildDefinition; 19 use Symfony\Component\DependencyInjection\ChildDefinition;
20 use Symfony\Component\DependencyInjection\ContainerBuilder; 20 use Symfony\Component\DependencyInjection\ContainerBuilder;
21 use Symfony\Component\DependencyInjection\ContainerInterface; 21 use Symfony\Component\DependencyInjection\ContainerInterface;
22 use Symfony\Component\DependencyInjection\Definition; 22 use Symfony\Component\DependencyInjection\Definition;
23 use Symfony\Component\DependencyInjection\Reference;
24 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; 23 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
25 use Symfony\Component\DependencyInjection\Exception\RuntimeException; 24 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
25 use Symfony\Component\DependencyInjection\Reference;
26 use Symfony\Component\ExpressionLanguage\Expression;
26 use Symfony\Component\Yaml\Exception\ParseException; 27 use Symfony\Component\Yaml\Exception\ParseException;
27 use Symfony\Component\Yaml\Parser as YamlParser; 28 use Symfony\Component\Yaml\Parser as YamlParser;
28 use Symfony\Component\Yaml\Tag\TaggedValue; 29 use Symfony\Component\Yaml\Tag\TaggedValue;
29 use Symfony\Component\Yaml\Yaml; 30 use Symfony\Component\Yaml\Yaml;
30 use Symfony\Component\ExpressionLanguage\Expression;
31 31
32 /** 32 /**
33 * YamlFileLoader loads YAML files service definitions. 33 * YamlFileLoader loads YAML files service definitions.
34 * 34 *
35 * @author Fabien Potencier <fabien@symfony.com> 35 * @author Fabien Potencier <fabien@symfony.com>
36 */ 36 */
37 class YamlFileLoader extends FileLoader 37 class YamlFileLoader extends FileLoader
38 { 38 {
39 private static $serviceKeywords = array( 39 private static $serviceKeywords = [
40 'alias' => 'alias', 40 'alias' => 'alias',
41 'parent' => 'parent', 41 'parent' => 'parent',
42 'class' => 'class', 42 'class' => 'class',
43 'shared' => 'shared', 43 'shared' => 'shared',
44 'synthetic' => 'synthetic', 44 'synthetic' => 'synthetic',
58 'decoration_priority' => 'decoration_priority', 58 'decoration_priority' => 'decoration_priority',
59 'autowire' => 'autowire', 59 'autowire' => 'autowire',
60 'autowiring_types' => 'autowiring_types', 60 'autowiring_types' => 'autowiring_types',
61 'autoconfigure' => 'autoconfigure', 61 'autoconfigure' => 'autoconfigure',
62 'bind' => 'bind', 62 'bind' => 'bind',
63 ); 63 ];
64 64
65 private static $prototypeKeywords = array( 65 private static $prototypeKeywords = [
66 'resource' => 'resource', 66 'resource' => 'resource',
67 'namespace' => 'namespace', 67 'namespace' => 'namespace',
68 'exclude' => 'exclude', 68 'exclude' => 'exclude',
69 'parent' => 'parent', 69 'parent' => 'parent',
70 'shared' => 'shared', 70 'shared' => 'shared',
79 'calls' => 'calls', 79 'calls' => 'calls',
80 'tags' => 'tags', 80 'tags' => 'tags',
81 'autowire' => 'autowire', 81 'autowire' => 'autowire',
82 'autoconfigure' => 'autoconfigure', 82 'autoconfigure' => 'autoconfigure',
83 'bind' => 'bind', 83 'bind' => 'bind',
84 ); 84 ];
85 85
86 private static $instanceofKeywords = array( 86 private static $instanceofKeywords = [
87 'shared' => 'shared', 87 'shared' => 'shared',
88 'lazy' => 'lazy', 88 'lazy' => 'lazy',
89 'public' => 'public', 89 'public' => 'public',
90 'properties' => 'properties', 90 'properties' => 'properties',
91 'configurator' => 'configurator', 91 'configurator' => 'configurator',
92 'calls' => 'calls', 92 'calls' => 'calls',
93 'tags' => 'tags', 93 'tags' => 'tags',
94 'autowire' => 'autowire', 94 'autowire' => 'autowire',
95 ); 95 ];
96 96
97 private static $defaultsKeywords = array( 97 private static $defaultsKeywords = [
98 'public' => 'public', 98 'public' => 'public',
99 'tags' => 'tags', 99 'tags' => 'tags',
100 'autowire' => 'autowire', 100 'autowire' => 'autowire',
101 'autoconfigure' => 'autoconfigure', 101 'autoconfigure' => 'autoconfigure',
102 'bind' => 'bind', 102 'bind' => 'bind',
103 ); 103 ];
104 104
105 private $yamlParser; 105 private $yamlParser;
106 106
107 private $anonymousServicesCount; 107 private $anonymousServicesCount;
108 private $anonymousServicesSuffix; 108 private $anonymousServicesSuffix;
126 // imports 126 // imports
127 $this->parseImports($content, $path); 127 $this->parseImports($content, $path);
128 128
129 // parameters 129 // parameters
130 if (isset($content['parameters'])) { 130 if (isset($content['parameters'])) {
131 if (!is_array($content['parameters'])) { 131 if (!\is_array($content['parameters'])) {
132 throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $path)); 132 throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $path));
133 } 133 }
134 134
135 foreach ($content['parameters'] as $key => $value) { 135 foreach ($content['parameters'] as $key => $value) {
136 $this->container->setParameter($key, $this->resolveServices($value, $path, true)); 136 $this->container->setParameter($key, $this->resolveServices($value, $path, true));
140 // extensions 140 // extensions
141 $this->loadFromExtensions($content); 141 $this->loadFromExtensions($content);
142 142
143 // services 143 // services
144 $this->anonymousServicesCount = 0; 144 $this->anonymousServicesCount = 0;
145 $this->anonymousServicesSuffix = ContainerBuilder::hash($path); 145 $this->anonymousServicesSuffix = '~'.ContainerBuilder::hash($path);
146 $this->setCurrentDir(dirname($path)); 146 $this->setCurrentDir(\dirname($path));
147 try { 147 try {
148 $this->parseDefinitions($content, $path); 148 $this->parseDefinitions($content, $path);
149 } finally { 149 } finally {
150 $this->instanceof = array(); 150 $this->instanceof = [];
151 } 151 }
152 } 152 }
153 153
154 /** 154 /**
155 * {@inheritdoc} 155 * {@inheritdoc}
156 */ 156 */
157 public function supports($resource, $type = null) 157 public function supports($resource, $type = null)
158 { 158 {
159 if (!is_string($resource)) { 159 if (!\is_string($resource)) {
160 return false; 160 return false;
161 } 161 }
162 162
163 if (null === $type && in_array(pathinfo($resource, PATHINFO_EXTENSION), array('yaml', 'yml'), true)) { 163 if (null === $type && \in_array(pathinfo($resource, PATHINFO_EXTENSION), ['yaml', 'yml'], true)) {
164 return true; 164 return true;
165 } 165 }
166 166
167 return in_array($type, array('yaml', 'yml'), true); 167 return \in_array($type, ['yaml', 'yml'], true);
168 } 168 }
169 169
170 /** 170 /**
171 * Parses all imports. 171 * Parses all imports.
172 * 172 *
177 { 177 {
178 if (!isset($content['imports'])) { 178 if (!isset($content['imports'])) {
179 return; 179 return;
180 } 180 }
181 181
182 if (!is_array($content['imports'])) { 182 if (!\is_array($content['imports'])) {
183 throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file)); 183 throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in %s. Check your YAML syntax.', $file));
184 } 184 }
185 185
186 $defaultDirectory = dirname($file); 186 $defaultDirectory = \dirname($file);
187 foreach ($content['imports'] as $import) { 187 foreach ($content['imports'] as $import) {
188 if (!is_array($import)) { 188 if (!\is_array($import)) {
189 $import = array('resource' => $import); 189 $import = ['resource' => $import];
190 } 190 }
191 if (!isset($import['resource'])) { 191 if (!isset($import['resource'])) {
192 throw new InvalidArgumentException(sprintf('An import should provide a resource in %s. Check your YAML syntax.', $file)); 192 throw new InvalidArgumentException(sprintf('An import should provide a resource in %s. Check your YAML syntax.', $file));
193 } 193 }
194 194
207 { 207 {
208 if (!isset($content['services'])) { 208 if (!isset($content['services'])) {
209 return; 209 return;
210 } 210 }
211 211
212 if (!is_array($content['services'])) { 212 if (!\is_array($content['services'])) {
213 throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file)); 213 throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
214 } 214 }
215 215
216 if (array_key_exists('_instanceof', $content['services'])) { 216 if (array_key_exists('_instanceof', $content['services'])) {
217 $instanceof = $content['services']['_instanceof']; 217 $instanceof = $content['services']['_instanceof'];
218 unset($content['services']['_instanceof']); 218 unset($content['services']['_instanceof']);
219 219
220 if (!is_array($instanceof)) { 220 if (!\is_array($instanceof)) {
221 throw new InvalidArgumentException(sprintf('Service "_instanceof" key must be an array, "%s" given in "%s".', gettype($instanceof), $file)); 221 throw new InvalidArgumentException(sprintf('Service "_instanceof" key must be an array, "%s" given in "%s".', \gettype($instanceof), $file));
222 } 222 }
223 $this->instanceof = array(); 223 $this->instanceof = [];
224 $this->isLoadingInstanceof = true; 224 $this->isLoadingInstanceof = true;
225 foreach ($instanceof as $id => $service) { 225 foreach ($instanceof as $id => $service) {
226 if (!$service || !is_array($service)) { 226 if (!$service || !\is_array($service)) {
227 throw new InvalidArgumentException(sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in %s. Check your YAML syntax.', $id, $file)); 227 throw new InvalidArgumentException(sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in %s. Check your YAML syntax.', $id, $file));
228 } 228 }
229 if (is_string($service) && 0 === strpos($service, '@')) { 229 if (\is_string($service) && 0 === strpos($service, '@')) {
230 throw new InvalidArgumentException(sprintf('Type definition "%s" cannot be an alias within "_instanceof" in %s. Check your YAML syntax.', $id, $file)); 230 throw new InvalidArgumentException(sprintf('Type definition "%s" cannot be an alias within "_instanceof" in %s. Check your YAML syntax.', $id, $file));
231 } 231 }
232 $this->parseDefinition($id, $service, $file, array()); 232 $this->parseDefinition($id, $service, $file, []);
233 } 233 }
234 } 234 }
235 235
236 $this->isLoadingInstanceof = false; 236 $this->isLoadingInstanceof = false;
237 $defaults = $this->parseDefaults($content, $file); 237 $defaults = $this->parseDefaults($content, $file);
249 * @throws InvalidArgumentException 249 * @throws InvalidArgumentException
250 */ 250 */
251 private function parseDefaults(array &$content, $file) 251 private function parseDefaults(array &$content, $file)
252 { 252 {
253 if (!array_key_exists('_defaults', $content['services'])) { 253 if (!array_key_exists('_defaults', $content['services'])) {
254 return array(); 254 return [];
255 } 255 }
256 $defaults = $content['services']['_defaults']; 256 $defaults = $content['services']['_defaults'];
257 unset($content['services']['_defaults']); 257 unset($content['services']['_defaults']);
258 258
259 if (!is_array($defaults)) { 259 if (!\is_array($defaults)) {
260 throw new InvalidArgumentException(sprintf('Service "_defaults" key must be an array, "%s" given in "%s".', gettype($defaults), $file)); 260 throw new InvalidArgumentException(sprintf('Service "_defaults" key must be an array, "%s" given in "%s".', \gettype($defaults), $file));
261 } 261 }
262 262
263 foreach ($defaults as $key => $default) { 263 foreach ($defaults as $key => $default) {
264 if (!isset(self::$defaultsKeywords[$key])) { 264 if (!isset(self::$defaultsKeywords[$key])) {
265 throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', self::$defaultsKeywords))); 265 throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', self::$defaultsKeywords)));
266 } 266 }
267 } 267 }
268 268
269 if (isset($defaults['tags'])) { 269 if (isset($defaults['tags'])) {
270 if (!is_array($tags = $defaults['tags'])) { 270 if (!\is_array($tags = $defaults['tags'])) {
271 throw new InvalidArgumentException(sprintf('Parameter "tags" in "_defaults" must be an array in %s. Check your YAML syntax.', $file)); 271 throw new InvalidArgumentException(sprintf('Parameter "tags" in "_defaults" must be an array in %s. Check your YAML syntax.', $file));
272 } 272 }
273 273
274 foreach ($tags as $tag) { 274 foreach ($tags as $tag) {
275 if (!is_array($tag)) { 275 if (!\is_array($tag)) {
276 $tag = array('name' => $tag); 276 $tag = ['name' => $tag];
277 } 277 }
278 278
279 if (!isset($tag['name'])) { 279 if (!isset($tag['name'])) {
280 throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in %s.', $file)); 280 throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in %s.', $file));
281 } 281 }
282 $name = $tag['name']; 282 $name = $tag['name'];
283 unset($tag['name']); 283 unset($tag['name']);
284 284
285 if (!is_string($name) || '' === $name) { 285 if (!\is_string($name) || '' === $name) {
286 throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in %s.', $file)); 286 throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in %s.', $file));
287 } 287 }
288 288
289 foreach ($tag as $attribute => $value) { 289 foreach ($tag as $attribute => $value) {
290 if (!is_scalar($value) && null !== $value) { 290 if (!is_scalar($value) && null !== $value) {
293 } 293 }
294 } 294 }
295 } 295 }
296 296
297 if (isset($defaults['bind'])) { 297 if (isset($defaults['bind'])) {
298 if (!is_array($defaults['bind'])) { 298 if (!\is_array($defaults['bind'])) {
299 throw new InvalidArgumentException(sprintf('Parameter "bind" in "_defaults" must be an array in %s. Check your YAML syntax.', $file)); 299 throw new InvalidArgumentException(sprintf('Parameter "bind" in "_defaults" must be an array in %s. Check your YAML syntax.', $file));
300 } 300 }
301 301
302 $defaults['bind'] = array_map(function ($v) { return new BoundArgument($v); }, $this->resolveServices($defaults['bind'], $file)); 302 $defaults['bind'] = array_map(function ($v) { return new BoundArgument($v); }, $this->resolveServices($defaults['bind'], $file));
303 } 303 }
311 * @return bool 311 * @return bool
312 */ 312 */
313 private function isUsingShortSyntax(array $service) 313 private function isUsingShortSyntax(array $service)
314 { 314 {
315 foreach ($service as $key => $value) { 315 foreach ($service as $key => $value) {
316 if (is_string($key) && ('' === $key || '$' !== $key[0])) { 316 if (\is_string($key) && ('' === $key || '$' !== $key[0])) {
317 return false; 317 return false;
318 } 318 }
319 } 319 }
320 320
321 return true; 321 return true;
334 private function parseDefinition($id, $service, $file, array $defaults) 334 private function parseDefinition($id, $service, $file, array $defaults)
335 { 335 {
336 if (preg_match('/^_[a-zA-Z0-9_]*$/', $id)) { 336 if (preg_match('/^_[a-zA-Z0-9_]*$/', $id)) {
337 @trigger_error(sprintf('Service names that start with an underscore are deprecated since Symfony 3.3 and will be reserved in 4.0. Rename the "%s" service or define it in XML instead.', $id), E_USER_DEPRECATED); 337 @trigger_error(sprintf('Service names that start with an underscore are deprecated since Symfony 3.3 and will be reserved in 4.0. Rename the "%s" service or define it in XML instead.', $id), E_USER_DEPRECATED);
338 } 338 }
339 if (is_string($service) && 0 === strpos($service, '@')) { 339 if (\is_string($service) && 0 === strpos($service, '@')) {
340 $this->container->setAlias($id, $alias = new Alias(substr($service, 1))); 340 $this->container->setAlias($id, $alias = new Alias(substr($service, 1)));
341 if (isset($defaults['public'])) { 341 if (isset($defaults['public'])) {
342 $alias->setPublic($defaults['public']); 342 $alias->setPublic($defaults['public']);
343 } 343 }
344 344
345 return; 345 return;
346 } 346 }
347 347
348 if (is_array($service) && $this->isUsingShortSyntax($service)) { 348 if (\is_array($service) && $this->isUsingShortSyntax($service)) {
349 $service = array('arguments' => $service); 349 $service = ['arguments' => $service];
350 } 350 }
351 351
352 if (null === $service) { 352 if (null === $service) {
353 $service = array(); 353 $service = [];
354 } 354 }
355 355
356 if (!is_array($service)) { 356 if (!\is_array($service)) {
357 throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', gettype($service), $id, $file)); 357 throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', \gettype($service), $id, $file));
358 } 358 }
359 359
360 $this->checkDefinition($id, $service, $file); 360 $this->checkDefinition($id, $service, $file);
361 361
362 if (isset($service['alias'])) { 362 if (isset($service['alias'])) {
366 } elseif (isset($defaults['public'])) { 366 } elseif (isset($defaults['public'])) {
367 $alias->setPublic($defaults['public']); 367 $alias->setPublic($defaults['public']);
368 } 368 }
369 369
370 foreach ($service as $key => $value) { 370 foreach ($service as $key => $value) {
371 if (!in_array($key, array('alias', 'public'))) { 371 if (!\in_array($key, ['alias', 'public'])) {
372 @trigger_error(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), E_USER_DEPRECATED); 372 @trigger_error(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), E_USER_DEPRECATED);
373 } 373 }
374 } 374 }
375 375
376 return; 376 return;
409 } 409 }
410 if (isset($defaults['autoconfigure'])) { 410 if (isset($defaults['autoconfigure'])) {
411 $definition->setAutoconfigured($defaults['autoconfigure']); 411 $definition->setAutoconfigured($defaults['autoconfigure']);
412 } 412 }
413 413
414 $definition->setChanges(array()); 414 $definition->setChanges([]);
415 } 415 }
416 416
417 if (isset($service['class'])) { 417 if (isset($service['class'])) {
418 $definition->setClass($service['class']); 418 $definition->setClass($service['class']);
419 } 419 }
461 if (isset($service['configurator'])) { 461 if (isset($service['configurator'])) {
462 $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file)); 462 $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file));
463 } 463 }
464 464
465 if (isset($service['calls'])) { 465 if (isset($service['calls'])) {
466 if (!is_array($service['calls'])) { 466 if (!\is_array($service['calls'])) {
467 throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); 467 throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
468 } 468 }
469 469
470 foreach ($service['calls'] as $call) { 470 foreach ($service['calls'] as $call) {
471 if (isset($call['method'])) { 471 if (isset($call['method'])) {
472 $method = $call['method']; 472 $method = $call['method'];
473 $args = isset($call['arguments']) ? $this->resolveServices($call['arguments'], $file) : array(); 473 $args = isset($call['arguments']) ? $this->resolveServices($call['arguments'], $file) : [];
474 } else { 474 } else {
475 $method = $call[0]; 475 $method = $call[0];
476 $args = isset($call[1]) ? $this->resolveServices($call[1], $file) : array(); 476 $args = isset($call[1]) ? $this->resolveServices($call[1], $file) : [];
477 } 477 }
478 478
479 if (!is_array($args)) { 479 if (!\is_array($args)) {
480 throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in %s. Check your YAML syntax.', $method, $id, $file)); 480 throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in %s. Check your YAML syntax.', $method, $id, $file));
481 } 481 }
482 $definition->addMethodCall($method, $args); 482 $definition->addMethodCall($method, $args);
483 } 483 }
484 } 484 }
485 485
486 $tags = isset($service['tags']) ? $service['tags'] : array(); 486 $tags = isset($service['tags']) ? $service['tags'] : [];
487 if (!is_array($tags)) { 487 if (!\is_array($tags)) {
488 throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); 488 throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
489 } 489 }
490 490
491 if (isset($defaults['tags'])) { 491 if (isset($defaults['tags'])) {
492 $tags = array_merge($tags, $defaults['tags']); 492 $tags = array_merge($tags, $defaults['tags']);
493 } 493 }
494 494
495 foreach ($tags as $tag) { 495 foreach ($tags as $tag) {
496 if (!is_array($tag)) { 496 if (!\is_array($tag)) {
497 $tag = array('name' => $tag); 497 $tag = ['name' => $tag];
498 } 498 }
499 499
500 if (!isset($tag['name'])) { 500 if (!isset($tag['name'])) {
501 throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file)); 501 throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
502 } 502 }
503 $name = $tag['name']; 503 $name = $tag['name'];
504 unset($tag['name']); 504 unset($tag['name']);
505 505
506 if (!is_string($name) || '' === $name) { 506 if (!\is_string($name) || '' === $name) {
507 throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', $id, $file)); 507 throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', $id, $file));
508 } 508 }
509 509
510 foreach ($tag as $attribute => $value) { 510 foreach ($tag as $attribute => $value) {
511 if (!is_scalar($value) && null !== $value) { 511 if (!is_scalar($value) && null !== $value) {
529 if (isset($service['autowire'])) { 529 if (isset($service['autowire'])) {
530 $definition->setAutowired($service['autowire']); 530 $definition->setAutowired($service['autowire']);
531 } 531 }
532 532
533 if (isset($service['autowiring_types'])) { 533 if (isset($service['autowiring_types'])) {
534 if (is_string($service['autowiring_types'])) { 534 if (\is_string($service['autowiring_types'])) {
535 $definition->addAutowiringType($service['autowiring_types']); 535 $definition->addAutowiringType($service['autowiring_types']);
536 } else { 536 } else {
537 if (!is_array($service['autowiring_types'])) { 537 if (!\is_array($service['autowiring_types'])) {
538 throw new InvalidArgumentException(sprintf('Parameter "autowiring_types" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); 538 throw new InvalidArgumentException(sprintf('Parameter "autowiring_types" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
539 } 539 }
540 540
541 foreach ($service['autowiring_types'] as $autowiringType) { 541 foreach ($service['autowiring_types'] as $autowiringType) {
542 if (!is_string($autowiringType)) { 542 if (!\is_string($autowiringType)) {
543 throw new InvalidArgumentException(sprintf('A "autowiring_types" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file)); 543 throw new InvalidArgumentException(sprintf('A "autowiring_types" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
544 } 544 }
545 545
546 $definition->addAutowiringType($autowiringType); 546 $definition->addAutowiringType($autowiringType);
547 } 547 }
548 } 548 }
549 } 549 }
550 550
551 if (isset($defaults['bind']) || isset($service['bind'])) { 551 if (isset($defaults['bind']) || isset($service['bind'])) {
552 // deep clone, to avoid multiple process of the same instance in the passes 552 // deep clone, to avoid multiple process of the same instance in the passes
553 $bindings = isset($defaults['bind']) ? unserialize(serialize($defaults['bind'])) : array(); 553 $bindings = isset($defaults['bind']) ? unserialize(serialize($defaults['bind'])) : [];
554 554
555 if (isset($service['bind'])) { 555 if (isset($service['bind'])) {
556 if (!is_array($service['bind'])) { 556 if (!\is_array($service['bind'])) {
557 throw new InvalidArgumentException(sprintf('Parameter "bind" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); 557 throw new InvalidArgumentException(sprintf('Parameter "bind" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
558 } 558 }
559 559
560 $bindings = array_merge($bindings, $this->resolveServices($service['bind'], $file)); 560 $bindings = array_merge($bindings, $this->resolveServices($service['bind'], $file));
561 } 561 }
574 if (array_key_exists('namespace', $service) && !array_key_exists('resource', $service)) { 574 if (array_key_exists('namespace', $service) && !array_key_exists('resource', $service)) {
575 throw new InvalidArgumentException(sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in %s. Check your YAML syntax.', $id, $file)); 575 throw new InvalidArgumentException(sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in %s. Check your YAML syntax.', $id, $file));
576 } 576 }
577 577
578 if (array_key_exists('resource', $service)) { 578 if (array_key_exists('resource', $service)) {
579 if (!is_string($service['resource'])) { 579 if (!\is_string($service['resource'])) {
580 throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file)); 580 throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
581 } 581 }
582 $exclude = isset($service['exclude']) ? $service['exclude'] : null; 582 $exclude = isset($service['exclude']) ? $service['exclude'] : null;
583 $namespace = isset($service['namespace']) ? $service['namespace'] : $id; 583 $namespace = isset($service['namespace']) ? $service['namespace'] : $id;
584 $this->registerClasses($definition, $namespace, $service['resource'], $exclude); 584 $this->registerClasses($definition, $namespace, $service['resource'], $exclude);
593 * @param string|array $callable A callable 593 * @param string|array $callable A callable
594 * @param string $parameter A parameter (e.g. 'factory' or 'configurator') 594 * @param string $parameter A parameter (e.g. 'factory' or 'configurator')
595 * @param string $id A service identifier 595 * @param string $id A service identifier
596 * @param string $file A parsed file 596 * @param string $file A parsed file
597 * 597 *
598 * @throws InvalidArgumentException When errors are occuried 598 * @throws InvalidArgumentException When errors occur
599 * 599 *
600 * @return string|array A parsed callable 600 * @return string|array A parsed callable
601 */ 601 */
602 private function parseCallable($callable, $parameter, $id, $file) 602 private function parseCallable($callable, $parameter, $id, $file)
603 { 603 {
604 if (is_string($callable)) { 604 if (\is_string($callable)) {
605 if ('' !== $callable && '@' === $callable[0]) { 605 if ('' !== $callable && '@' === $callable[0]) {
606 throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $parameter, $id, $callable, substr($callable, 1))); 606 throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $parameter, $id, $callable, substr($callable, 1)));
607 } 607 }
608 608
609 if (false !== strpos($callable, ':') && false === strpos($callable, '::')) { 609 if (false !== strpos($callable, ':') && false === strpos($callable, '::')) {
610 $parts = explode(':', $callable); 610 $parts = explode(':', $callable);
611 611
612 return array($this->resolveServices('@'.$parts[0], $file), $parts[1]); 612 return [$this->resolveServices('@'.$parts[0], $file), $parts[1]];
613 } 613 }
614 614
615 return $callable; 615 return $callable;
616 } 616 }
617 617
618 if (is_array($callable)) { 618 if (\is_array($callable)) {
619 if (isset($callable[0]) && isset($callable[1])) { 619 if (isset($callable[0]) && isset($callable[1])) {
620 return array($this->resolveServices($callable[0], $file), $callable[1]); 620 return [$this->resolveServices($callable[0], $file), $callable[1]];
621 } 621 }
622 622
623 if ('factory' === $parameter && isset($callable[1]) && null === $callable[0]) { 623 if ('factory' === $parameter && isset($callable[1]) && null === $callable[0]) {
624 return $callable; 624 return $callable;
625 } 625 }
664 }); 664 });
665 665
666 try { 666 try {
667 $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS); 667 $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS);
668 } catch (ParseException $e) { 668 } catch (ParseException $e) {
669 throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $file), 0, $e); 669 throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: %s', $file, $e->getMessage()), 0, $e);
670 } finally { 670 } finally {
671 restore_error_handler(); 671 restore_error_handler();
672 } 672 }
673 673
674 return $this->validate($configuration, $file); 674 return $this->validate($configuration, $file);
688 { 688 {
689 if (null === $content) { 689 if (null === $content) {
690 return $content; 690 return $content;
691 } 691 }
692 692
693 if (!is_array($content)) { 693 if (!\is_array($content)) {
694 throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file)); 694 throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file));
695 } 695 }
696 696
697 foreach ($content as $namespace => $data) { 697 foreach ($content as $namespace => $data) {
698 if (in_array($namespace, array('imports', 'parameters', 'services'))) { 698 if (\in_array($namespace, ['imports', 'parameters', 'services'])) {
699 continue; 699 continue;
700 } 700 }
701 701
702 if (!$this->container->hasExtension($namespace)) { 702 if (!$this->container->hasExtension($namespace)) {
703 $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions())); 703 $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
704 throw new InvalidArgumentException(sprintf( 704 throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s', $namespace, $file, $namespace, $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'));
705 'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
706 $namespace,
707 $file,
708 $namespace,
709 $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
710 ));
711 } 705 }
712 } 706 }
713 707
714 return $content; 708 return $content;
715 } 709 }
726 private function resolveServices($value, $file, $isParameter = false) 720 private function resolveServices($value, $file, $isParameter = false)
727 { 721 {
728 if ($value instanceof TaggedValue) { 722 if ($value instanceof TaggedValue) {
729 $argument = $value->getValue(); 723 $argument = $value->getValue();
730 if ('iterator' === $value->getTag()) { 724 if ('iterator' === $value->getTag()) {
731 if (!is_array($argument)) { 725 if (!\is_array($argument)) {
732 throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts sequences in "%s".', $file)); 726 throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts sequences in "%s".', $file));
733 } 727 }
734 $argument = $this->resolveServices($argument, $file, $isParameter); 728 $argument = $this->resolveServices($argument, $file, $isParameter);
735 try { 729 try {
736 return new IteratorArgument($argument); 730 return new IteratorArgument($argument);
737 } catch (InvalidArgumentException $e) { 731 } catch (InvalidArgumentException $e) {
738 throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts arrays of "@service" references in "%s".', $file)); 732 throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts arrays of "@service" references in "%s".', $file));
739 } 733 }
740 } 734 }
741 if ('tagged' === $value->getTag()) { 735 if ('tagged' === $value->getTag()) {
742 if (!is_string($argument) || !$argument) { 736 if (!\is_string($argument) || !$argument) {
743 throw new InvalidArgumentException(sprintf('"!tagged" tag only accepts non empty string in "%s".', $file)); 737 throw new InvalidArgumentException(sprintf('"!tagged" tag only accepts non empty string in "%s".', $file));
744 } 738 }
745 739
746 return new TaggedIteratorArgument($argument); 740 return new TaggedIteratorArgument($argument);
747 } 741 }
751 } 745 }
752 746
753 $isLoadingInstanceof = $this->isLoadingInstanceof; 747 $isLoadingInstanceof = $this->isLoadingInstanceof;
754 $this->isLoadingInstanceof = false; 748 $this->isLoadingInstanceof = false;
755 $instanceof = $this->instanceof; 749 $instanceof = $this->instanceof;
756 $this->instanceof = array(); 750 $this->instanceof = [];
757 751
758 $id = sprintf('%d_%s', ++$this->anonymousServicesCount, preg_replace('/^.*\\\\/', '', isset($argument['class']) ? $argument['class'] : '').$this->anonymousServicesSuffix); 752 $id = sprintf('%d_%s', ++$this->anonymousServicesCount, preg_replace('/^.*\\\\/', '', isset($argument['class']) ? $argument['class'] : '').$this->anonymousServicesSuffix);
759 $this->parseDefinition($id, $argument, $file, array()); 753 $this->parseDefinition($id, $argument, $file, []);
760 754
761 if (!$this->container->hasDefinition($id)) { 755 if (!$this->container->hasDefinition($id)) {
762 throw new InvalidArgumentException(sprintf('Creating an alias using the tag "!service" is not allowed in "%s".', $file)); 756 throw new InvalidArgumentException(sprintf('Creating an alias using the tag "!service" is not allowed in "%s".', $file));
763 } 757 }
764 758
771 } 765 }
772 766
773 throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag())); 767 throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag()));
774 } 768 }
775 769
776 if (is_array($value)) { 770 if (\is_array($value)) {
777 foreach ($value as $k => $v) { 771 foreach ($value as $k => $v) {
778 $value[$k] = $this->resolveServices($v, $file, $isParameter); 772 $value[$k] = $this->resolveServices($v, $file, $isParameter);
779 } 773 }
780 } elseif (is_string($value) && 0 === strpos($value, '@=')) { 774 } elseif (\is_string($value) && 0 === strpos($value, '@=')) {
781 if (!class_exists(Expression::class)) { 775 if (!class_exists(Expression::class)) {
782 throw new \LogicException(sprintf('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".')); 776 throw new \LogicException(sprintf('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".'));
783 } 777 }
784 778
785 return new Expression(substr($value, 2)); 779 return new Expression(substr($value, 2));
786 } elseif (is_string($value) && 0 === strpos($value, '@')) { 780 } elseif (\is_string($value) && 0 === strpos($value, '@')) {
787 if (0 === strpos($value, '@@')) { 781 if (0 === strpos($value, '@@')) {
788 $value = substr($value, 1); 782 $value = substr($value, 1);
789 $invalidBehavior = null; 783 $invalidBehavior = null;
790 } elseif (0 === strpos($value, '@!')) { 784 } elseif (0 === strpos($value, '@!')) {
791 $value = substr($value, 2); 785 $value = substr($value, 2);
815 * Loads from Extensions. 809 * Loads from Extensions.
816 */ 810 */
817 private function loadFromExtensions(array $content) 811 private function loadFromExtensions(array $content)
818 { 812 {
819 foreach ($content as $namespace => $values) { 813 foreach ($content as $namespace => $values) {
820 if (in_array($namespace, array('imports', 'parameters', 'services'))) { 814 if (\in_array($namespace, ['imports', 'parameters', 'services'])) {
821 continue; 815 continue;
822 } 816 }
823 817
824 if (!is_array($values) && null !== $values) { 818 if (!\is_array($values) && null !== $values) {
825 $values = array(); 819 $values = [];
826 } 820 }
827 821
828 $this->container->loadFromExtension($namespace, $values); 822 $this->container->loadFromExtension($namespace, $values);
829 } 823 }
830 } 824 }