231 lines
12 KiB
YAML
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
|