comparison vendor/symfony/dependency-injection/Compiler/AutowirePass.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents c2387f117808
children af1871eacc83
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
26 * @author Kévin Dunglas <dunglas@gmail.com> 26 * @author Kévin Dunglas <dunglas@gmail.com>
27 * @author Nicolas Grekas <p@tchwork.com> 27 * @author Nicolas Grekas <p@tchwork.com>
28 */ 28 */
29 class AutowirePass extends AbstractRecursivePass 29 class AutowirePass extends AbstractRecursivePass
30 { 30 {
31 private $definedTypes = array(); 31 private $definedTypes = [];
32 private $types; 32 private $types;
33 private $ambiguousServiceTypes; 33 private $ambiguousServiceTypes;
34 private $autowired = array(); 34 private $autowired = [];
35 private $lastFailure; 35 private $lastFailure;
36 private $throwOnAutowiringException; 36 private $throwOnAutowiringException;
37 private $autowiringExceptions = array(); 37 private $autowiringExceptions = [];
38 private $strictMode; 38 private $strictMode;
39 39
40 /** 40 /**
41 * @param bool $throwOnAutowireException Errors can be retrieved via Definition::getErrors() 41 * @param bool $throwOnAutowireException Errors can be retrieved via Definition::getErrors()
42 */ 42 */
61 * {@inheritdoc} 61 * {@inheritdoc}
62 */ 62 */
63 public function process(ContainerBuilder $container) 63 public function process(ContainerBuilder $container)
64 { 64 {
65 // clear out any possibly stored exceptions from before 65 // clear out any possibly stored exceptions from before
66 $this->autowiringExceptions = array(); 66 $this->autowiringExceptions = [];
67 $this->strictMode = $container->hasParameter('container.autowiring.strict_mode') && $container->getParameter('container.autowiring.strict_mode'); 67 $this->strictMode = $container->hasParameter('container.autowiring.strict_mode') && $container->getParameter('container.autowiring.strict_mode');
68 68
69 try { 69 try {
70 parent::process($container); 70 parent::process($container);
71 } finally { 71 } finally {
72 $this->definedTypes = array(); 72 $this->definedTypes = [];
73 $this->types = null; 73 $this->types = null;
74 $this->ambiguousServiceTypes = null; 74 $this->ambiguousServiceTypes = null;
75 $this->autowired = array(); 75 $this->autowired = [];
76 } 76 }
77 } 77 }
78 78
79 /** 79 /**
80 * Creates a resource to help know if this service has changed. 80 * Creates a resource to help know if this service has changed.
87 */ 87 */
88 public static function createResourceForClass(\ReflectionClass $reflectionClass) 88 public static function createResourceForClass(\ReflectionClass $reflectionClass)
89 { 89 {
90 @trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.', E_USER_DEPRECATED); 90 @trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.', E_USER_DEPRECATED);
91 91
92 $metadata = array(); 92 $metadata = [];
93 93
94 foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) { 94 foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
95 if (!$reflectionMethod->isStatic()) { 95 if (!$reflectionMethod->isStatic()) {
96 $metadata[$reflectionMethod->name] = self::getResourceMetadataForMethod($reflectionMethod); 96 $metadata[$reflectionMethod->name] = self::getResourceMetadataForMethod($reflectionMethod);
97 } 97 }
145 } catch (RuntimeException $e) { 145 } catch (RuntimeException $e) {
146 throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e); 146 throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e);
147 } 147 }
148 148
149 if ($constructor) { 149 if ($constructor) {
150 array_unshift($methodCalls, array($constructor, $value->getArguments())); 150 array_unshift($methodCalls, [$constructor, $value->getArguments()]);
151 } 151 }
152 152
153 $methodCalls = $this->autowireCalls($reflectionClass, $methodCalls); 153 $methodCalls = $this->autowireCalls($reflectionClass, $methodCalls);
154 154
155 if ($constructor) { 155 if ($constructor) {
325 /** 325 /**
326 * Populates the list of available types. 326 * Populates the list of available types.
327 */ 327 */
328 private function populateAvailableTypes($onlyAutowiringTypes = false) 328 private function populateAvailableTypes($onlyAutowiringTypes = false)
329 { 329 {
330 $this->types = array(); 330 $this->types = [];
331 if (!$onlyAutowiringTypes) { 331 if (!$onlyAutowiringTypes) {
332 $this->ambiguousServiceTypes = array(); 332 $this->ambiguousServiceTypes = [];
333 } 333 }
334 334
335 foreach ($this->container->getDefinitions() as $id => $definition) { 335 foreach ($this->container->getDefinitions() as $id => $definition) {
336 $this->populateAvailableType($id, $definition, $onlyAutowiringTypes); 336 $this->populateAvailableType($id, $definition, $onlyAutowiringTypes);
337 } 337 }
399 return; 399 return;
400 } 400 }
401 401
402 // keep an array of all services matching this type 402 // keep an array of all services matching this type
403 if (!isset($this->ambiguousServiceTypes[$type])) { 403 if (!isset($this->ambiguousServiceTypes[$type])) {
404 $this->ambiguousServiceTypes[$type] = array($this->types[$type]); 404 $this->ambiguousServiceTypes[$type] = [$this->types[$type]];
405 unset($this->types[$type]); 405 unset($this->types[$type]);
406 } 406 }
407 $this->ambiguousServiceTypes[$type][] = $id; 407 $this->ambiguousServiceTypes[$type][] = $id;
408 } 408 }
409 409
450 return new TypedReference($argumentId, $type); 450 return new TypedReference($argumentId, $type);
451 } 451 }
452 452
453 private function createTypeNotFoundMessage(TypedReference $reference, $label) 453 private function createTypeNotFoundMessage(TypedReference $reference, $label)
454 { 454 {
455 if (!$r = $this->container->getReflectionClass($type = $reference->getType(), false)) { 455 $trackResources = $this->container->isTrackingResources();
456 $this->container->setResourceTracking(false);
457 try {
458 if ($r = $this->container->getReflectionClass($type = $reference->getType(), false)) {
459 $alternatives = $this->createTypeAlternatives($reference);
460 }
461 } finally {
462 $this->container->setResourceTracking($trackResources);
463 }
464
465 if (!$r) {
456 // either $type does not exist or a parent class does not exist 466 // either $type does not exist or a parent class does not exist
457 try { 467 try {
458 $resource = new ClassExistenceResource($type, false); 468 $resource = new ClassExistenceResource($type, false);
459 // isFresh() will explode ONLY if a parent class/trait does not exist 469 // isFresh() will explode ONLY if a parent class/trait does not exist
460 $resource->isFresh(0); 470 $resource->isFresh(0);
463 $parentMsg = $e->getMessage(); 473 $parentMsg = $e->getMessage();
464 } 474 }
465 475
466 $message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found'); 476 $message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found');
467 } else { 477 } else {
468 $alternatives = $this->createTypeAlternatives($reference);
469 $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists'; 478 $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists';
470 $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives); 479 $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives);
471 480
472 if ($r->isInterface() && !$alternatives) { 481 if ($r->isInterface() && !$alternatives) {
473 $message .= ' Did you create a class that implements this interface?'; 482 $message .= ' Did you create a class that implements this interface?';
510 /** 519 /**
511 * @deprecated since version 3.3, to be removed in 4.0. 520 * @deprecated since version 3.3, to be removed in 4.0.
512 */ 521 */
513 private static function getResourceMetadataForMethod(\ReflectionMethod $method) 522 private static function getResourceMetadataForMethod(\ReflectionMethod $method)
514 { 523 {
515 $methodArgumentsMetadata = array(); 524 $methodArgumentsMetadata = [];
516 foreach ($method->getParameters() as $parameter) { 525 foreach ($method->getParameters() as $parameter) {
517 try { 526 try {
518 $class = $parameter->getClass(); 527 $class = $parameter->getClass();
519 } catch (\ReflectionException $e) { 528 } catch (\ReflectionException $e) {
520 // type-hint is against a non-existent class 529 // type-hint is against a non-existent class
521 $class = false; 530 $class = false;
522 } 531 }
523 532
524 $isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic(); 533 $isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic();
525 $methodArgumentsMetadata[] = array( 534 $methodArgumentsMetadata[] = [
526 'class' => $class, 535 'class' => $class,
527 'isOptional' => $parameter->isOptional(), 536 'isOptional' => $parameter->isOptional(),
528 'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null, 537 'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null,
529 ); 538 ];
530 } 539 }
531 540
532 return $methodArgumentsMetadata; 541 return $methodArgumentsMetadata;
533 } 542 }
534 543
535 private function getAliasesSuggestionForType($type, $extraContext = null) 544 private function getAliasesSuggestionForType($type, $extraContext = null)
536 { 545 {
537 $aliases = array(); 546 $aliases = [];
538 foreach (class_parents($type) + class_implements($type) as $parent) { 547 foreach (class_parents($type) + class_implements($type) as $parent) {
539 if ($this->container->has($parent) && !$this->container->findDefinition($parent)->isAbstract()) { 548 if ($this->container->has($parent) && !$this->container->findDefinition($parent)->isAbstract()) {
540 $aliases[] = $parent; 549 $aliases[] = $parent;
541 } 550 }
542 } 551 }
543 552
544 $extraContext = $extraContext ? ' '.$extraContext : ''; 553 $extraContext = $extraContext ? ' '.$extraContext : '';
545 if (1 < $len = count($aliases)) { 554 if (1 < $len = \count($aliases)) {
546 $message = sprintf('Try changing the type-hint%s to one of its parents: ', $extraContext); 555 $message = sprintf('Try changing the type-hint%s to one of its parents: ', $extraContext);
547 for ($i = 0, --$len; $i < $len; ++$i) { 556 for ($i = 0, --$len; $i < $len; ++$i) {
548 $message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]); 557 $message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
549 } 558 }
550 $message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]); 559 $message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);