api/symfony/Component/DependencyInjection/Compiler/AutowirePass.yaml
2024-09-26 02:03:21 -07:00

231 lines
12 KiB
YAML

name: AutowirePass
class_comment: "# * Inspects existing service definitions and wires the autowired\
\ ones using the type hints of their classes.\n# *\n# * @author K\xE9vin Dunglas\
\ <dunglas@gmail.com>\n# * @author Nicolas Grekas <p@tchwork.com>"
dependencies:
- name: ClassExistenceResource
type: class
source: Symfony\Component\Config\Resource\ClassExistenceResource
- name: Autowire
type: class
source: Symfony\Component\DependencyInjection\Attribute\Autowire
- name: AutowireDecorated
type: class
source: Symfony\Component\DependencyInjection\Attribute\AutowireDecorated
- name: AutowireInline
type: class
source: Symfony\Component\DependencyInjection\Attribute\AutowireInline
- name: Lazy
type: class
source: Symfony\Component\DependencyInjection\Attribute\Lazy
- name: Target
type: class
source: Symfony\Component\DependencyInjection\Attribute\Target
- name: ContainerBuilder
type: class
source: Symfony\Component\DependencyInjection\ContainerBuilder
- name: ContainerInterface
type: class
source: Symfony\Component\DependencyInjection\ContainerInterface
- name: Definition
type: class
source: Symfony\Component\DependencyInjection\Definition
- name: AutowiringFailedException
type: class
source: Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
- name: ParameterNotFoundException
type: class
source: Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException
- name: RuntimeException
type: class
source: Symfony\Component\DependencyInjection\Exception\RuntimeException
- name: Reference
type: class
source: Symfony\Component\DependencyInjection\Reference
- name: TypedReference
type: class
source: Symfony\Component\DependencyInjection\TypedReference
- name: ProxyHelper
type: class
source: Symfony\Component\VarExporter\ProxyHelper
properties:
- name: value
visibility: public
comment: null
- name: names
visibility: public
comment: null
- name: bag
visibility: public
comment: null
methods:
- name: autowireMethod
visibility: private
parameters:
- name: reflectionMethod
- name: arguments
- name: checkAttributes
comment: "# * Inspects existing service definitions and wires the autowired ones\
\ using the type hints of their classes.\n# *\n# * @author K\xE9vin Dunglas <dunglas@gmail.com>\n\
# * @author Nicolas Grekas <p@tchwork.com>\n# */\n# class AutowirePass extends\
\ AbstractRecursivePass\n# {\n# protected bool $skipScalars = true;\n# \n# private\
\ array $types;\n# private array $ambiguousServiceTypes;\n# private array $autowiringAliases;\n\
# private ?string $lastFailure = null;\n# private ?string $decoratedClass = null;\n\
# private ?string $decoratedId = null;\n# private object $defaultArgument;\n#\
\ private ?\\Closure $restorePreviousValue = null;\n# private ?self $typesClone\
\ = null;\n# \n# public function __construct(\n# private bool $throwOnAutowiringException\
\ = true,\n# ) {\n# $this->defaultArgument = new class {\n# public $value;\n#\
\ public $names;\n# public $bag;\n# \n# public function withValue(\\ReflectionParameter\
\ $parameter): self\n# {\n# $clone = clone $this;\n# $clone->value = $this->bag->escapeValue($parameter->getDefaultValue());\n\
# \n# return $clone;\n# }\n# };\n# }\n# \n# public function process(ContainerBuilder\
\ $container): void\n# {\n# $this->defaultArgument->bag = $container->getParameterBag();\n\
# \n# try {\n# $this->typesClone = clone $this;\n# parent::process($container);\n\
# } finally {\n# $this->decoratedClass = null;\n# $this->decoratedId = null;\n\
# $this->defaultArgument->bag = null;\n# $this->defaultArgument->names = null;\n\
# $this->restorePreviousValue = null;\n# $this->typesClone = null;\n# }\n# }\n\
# \n# protected function processValue(mixed $value, bool $isRoot = false): mixed\n\
# {\n# if ($value instanceof Autowire) {\n# return $this->processValue($this->container->getParameterBag()->resolveValue($value->value));\n\
# }\n# \n# if ($value instanceof AutowireDecorated) {\n# $definition = $this->container->getDefinition($this->currentId);\n\
# \n# return new Reference($definition->innerServiceId ?? $this->currentId.'.inner',\
\ $definition->decorationOnInvalid ?? ContainerInterface::NULL_ON_INVALID_REFERENCE);\n\
# }\n# \n# try {\n# return $this->doProcessValue($value, $isRoot);\n# } catch\
\ (AutowiringFailedException $e) {\n# if ($this->throwOnAutowiringException) {\n\
# throw $e;\n# }\n# \n# $this->container->getDefinition($this->currentId)->addError($e->getMessageCallback()\
\ ?? $e->getMessage());\n# \n# return parent::processValue($value, $isRoot);\n\
# }\n# }\n# \n# private function doProcessValue(mixed $value, bool $isRoot = false):\
\ mixed\n# {\n# if ($value instanceof TypedReference) {\n# foreach ($value->getAttributes()\
\ as $attribute) {\n# if ($attribute === $v = $this->processValue($attribute))\
\ {\n# continue;\n# }\n# if (!$attribute instanceof Autowire || !$v instanceof\
\ Reference) {\n# return $v;\n# }\n# \n# $invalidBehavior = ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE\
\ !== $v->getInvalidBehavior() ? $v->getInvalidBehavior() : $value->getInvalidBehavior();\n\
# $value = $v instanceof TypedReference\n# ? new TypedReference($v, $v->getType(),\
\ $invalidBehavior, $v->getName() ?? $value->getName(), array_merge($v->getAttributes(),\
\ $value->getAttributes()))\n# : new TypedReference($v, $value->getType(), $invalidBehavior,\
\ $value->getName(), $value->getAttributes());\n# break;\n# }\n# if ($ref = $this->getAutowiredReference($value,\
\ true)) {\n# return $ref;\n# }\n# if (ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE\
\ === $value->getInvalidBehavior()) {\n# $message = $this->createTypeNotFoundMessageCallback($value,\
\ 'it');\n# \n# // since the error message varies by referenced id and $this->currentId,\
\ so should the id of the dummy errored definition\n# $this->container->register($id\
\ = \\sprintf('.errored.%s.%s', $this->currentId, (string) $value), $value->getType())\n\
# ->addError($message);\n# \n# return new TypedReference($id, $value->getType(),\
\ $value->getInvalidBehavior(), $value->getName());\n# }\n# }\n# $value = parent::processValue($value,\
\ $isRoot);\n# \n# if (!$value instanceof Definition || !$value->isAutowired()\
\ || $value->isAbstract() || !$value->getClass()) {\n# return $value;\n# }\n#\
\ if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(),\
\ false)) {\n# $this->container->log($this, \\sprintf('Skipping service \"%s\"\
: Class or interface \"%s\" cannot be loaded.', $this->currentId, $value->getClass()));\n\
# \n# return $value;\n# }\n# \n# $methodCalls = $value->getMethodCalls();\n# \n\
# try {\n# $constructor = $this->getConstructor($value, false);\n# } catch (RuntimeException\
\ $e) {\n# throw new AutowiringFailedException($this->currentId, $e->getMessage(),\
\ 0, $e);\n# }\n# \n# if ($constructor) {\n# array_unshift($methodCalls, [$constructor,\
\ $value->getArguments()]);\n# }\n# \n# $checkAttributes = !$value->hasTag('container.ignore_attributes');\n\
# $methodCalls = $this->autowireCalls($methodCalls, $reflectionClass, $isRoot,\
\ $checkAttributes);\n# \n# if ($constructor) {\n# [, $arguments] = array_shift($methodCalls);\n\
# \n# if ($arguments !== $value->getArguments()) {\n# $value->setArguments($arguments);\n\
# }\n# }\n# \n# if ($methodCalls !== $value->getMethodCalls()) {\n# $value->setMethodCalls($methodCalls);\n\
# }\n# \n# return $value;\n# }\n# \n# private function autowireCalls(array $methodCalls,\
\ \\ReflectionClass $reflectionClass, bool $isRoot, bool $checkAttributes): array\n\
# {\n# if ($isRoot) {\n# $this->decoratedId = null;\n# $this->decoratedClass =\
\ null;\n# $this->restorePreviousValue = null;\n# \n# if (($definition = $this->container->getDefinition($this->currentId))\
\ && null !== ($this->decoratedId = $definition->innerServiceId) && $this->container->has($this->decoratedId))\
\ {\n# $this->decoratedClass = $this->container->findDefinition($this->decoratedId)->getClass();\n\
# }\n# }\n# \n# $patchedIndexes = [];\n# \n# foreach ($methodCalls as $i => $call)\
\ {\n# [$method, $arguments] = $call;\n# \n# if ($method instanceof \\ReflectionFunctionAbstract)\
\ {\n# $reflectionMethod = $method;\n# } else {\n# $definition = new Definition($reflectionClass->name);\n\
# try {\n# $reflectionMethod = $this->getReflectionMethod($definition, $method);\n\
# } catch (RuntimeException $e) {\n# if ($definition->getFactory()) {\n# continue;\n\
# }\n# throw $e;\n# }\n# }\n# \n# $arguments = $this->autowireMethod($reflectionMethod,\
\ $arguments, $checkAttributes);\n# \n# if ($arguments !== $call[1]) {\n# $methodCalls[$i][1]\
\ = $arguments;\n# $patchedIndexes[] = $i;\n# }\n# }\n# \n# // use named arguments\
\ to skip complex default values\n# foreach ($patchedIndexes as $i) {\n# $namedArguments\
\ = null;\n# $arguments = $methodCalls[$i][1];\n# \n# foreach ($arguments as $j\
\ => $value) {\n# if ($namedArguments && !$value instanceof $this->defaultArgument)\
\ {\n# unset($arguments[$j]);\n# $arguments[$namedArguments[$j]] = $value;\n#\
\ }\n# if (!$value instanceof $this->defaultArgument) {\n# continue;\n# }\n# \n\
# if (\\is_array($value->value) ? $value->value : \\is_object($value->value))\
\ {\n# unset($arguments[$j]);\n# $namedArguments = $value->names;\n# }\n# \n#\
\ if ($namedArguments) {\n# unset($arguments[$j]);\n# } else {\n# $arguments[$j]\
\ = $value->value;\n# }\n# }\n# \n# $methodCalls[$i][1] = $arguments;\n# }\n#\
\ \n# return $methodCalls;\n# }\n# \n# /**\n# * Autowires the constructor or a\
\ method.\n# *\n# * @throws AutowiringFailedException"
- name: getAutowiredReference
visibility: private
parameters:
- name: reference
- name: filterType
comment: '# * Returns a reference to the service matching the given type, if any.'
- name: populateAvailableTypes
visibility: private
parameters:
- name: container
comment: '# * Populates the list of available types.'
- name: populateAvailableType
visibility: private
parameters:
- name: container
- name: id
- name: definition
comment: '# * Populates the list of available types for a given definition.'
- name: set
visibility: private
parameters:
- name: type
- name: id
comment: '# * Associates a type and a service id if applicable.'
- name: createTypeNotFoundMessageCallback
visibility: private
parameters:
- name: reference
- name: label
comment: null
- name: createTypeNotFoundMessage
visibility: private
parameters:
- name: reference
- name: label
- name: currentId
comment: null
- name: createTypeAlternatives
visibility: private
parameters:
- name: container
- name: reference
comment: null
- name: getAliasesSuggestionForType
visibility: private
parameters:
- name: container
- name: type
comment: null
- name: populateAutowiringAlias
visibility: private
parameters:
- name: id
- name: target
default: 'null'
comment: null
- name: getCombinedAlias
visibility: private
parameters:
- name: type
- name: name
default: 'null'
comment: null
traits:
- Symfony\Component\Config\Resource\ClassExistenceResource
- Symfony\Component\DependencyInjection\Attribute\Autowire
- Symfony\Component\DependencyInjection\Attribute\AutowireDecorated
- Symfony\Component\DependencyInjection\Attribute\AutowireInline
- Symfony\Component\DependencyInjection\Attribute\Lazy
- Symfony\Component\DependencyInjection\Attribute\Target
- Symfony\Component\DependencyInjection\ContainerBuilder
- Symfony\Component\DependencyInjection\ContainerInterface
- Symfony\Component\DependencyInjection\Definition
- Symfony\Component\DependencyInjection\Exception\AutowiringFailedException
- Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException
- Symfony\Component\DependencyInjection\Exception\RuntimeException
- Symfony\Component\DependencyInjection\Reference
- Symfony\Component\DependencyInjection\TypedReference
- Symfony\Component\VarExporter\ProxyHelper
interfaces:
- this