From 2284a40a8ef079658c267a35b38828c8462d5615 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Thu, 18 Nov 2021 22:51:28 +0300 Subject: [PATCH] Remove ArrayDefinitionBuilder (#22) --- src/ArrayDefinition.php | 98 +++++++++++- src/Infrastructure/ArrayDefinitionBuilder.php | 151 ------------------ 2 files changed, 96 insertions(+), 153 deletions(-) delete mode 100644 src/Infrastructure/ArrayDefinitionBuilder.php diff --git a/src/ArrayDefinition.php b/src/ArrayDefinition.php index 9d4fad8..7784564 100644 --- a/src/ArrayDefinition.php +++ b/src/ArrayDefinition.php @@ -6,8 +6,10 @@ use Psr\Container\ContainerInterface; use Yiisoft\Definitions\Contract\DefinitionInterface; -use Yiisoft\Definitions\Infrastructure\ArrayDefinitionBuilder; +use Yiisoft\Definitions\Exception\InvalidConfigException; +use Yiisoft\Definitions\Infrastructure\DefinitionExtractor; +use Yiisoft\Definitions\Infrastructure\DefinitionResolver; use function count; /** @@ -129,7 +131,99 @@ public function getMethodsAndProperties(): array public function resolve(ContainerInterface $container): object { - return ArrayDefinitionBuilder::getInstance()->build($container, $this->referenceContainer, $this); + $class = $this->getClass(); + $dependencies = DefinitionExtractor::getInstance()->fromClassName($class); + $constructorArguments = $this->getConstructorArguments(); + + $this->injectArguments($dependencies, $constructorArguments); + + $resolved = DefinitionResolver::resolveArray($container, $this->referenceContainer, $dependencies); + + /** @psalm-suppress MixedMethodCall */ + $object = new $class(...array_values($resolved)); + + foreach ($this->getMethodsAndProperties() as $item) { + /** @var mixed $value */ + [$type, $name, $value] = $item; + /** @var mixed */ + $value = DefinitionResolver::resolve($container, $this->referenceContainer, $value); + if ($type === self::TYPE_METHOD) { + /** @var mixed */ + $setter = call_user_func_array([$object, $name], $value); + if ($setter instanceof $object) { + /** @var object */ + $object = $setter; + } + } elseif ($type === self::TYPE_PROPERTY) { + $object->$name = $value; + } + } + + return $object; + } + + /** + * @psalm-param array $dependencies + * + * @throws InvalidConfigException + */ + private function injectArguments(array &$dependencies, array $arguments): void + { + $isIntegerIndexed = $this->isIntegerIndexed($arguments); + $dependencyIndex = 0; + $usedArguments = []; + $isVariadic = false; + foreach ($dependencies as $key => &$value) { + if ($value instanceof ParameterDefinition && $value->isVariadic()) { + $isVariadic = true; + } + $index = $isIntegerIndexed ? $dependencyIndex : $key; + if (array_key_exists($index, $arguments)) { + $value = DefinitionResolver::ensureResolvable($arguments[$index]); + $usedArguments[$index] = 1; + } + $dependencyIndex++; + } + unset($value); + if ($isVariadic) { + /** @var mixed $value */ + foreach ($arguments as $index => $value) { + if (!isset($usedArguments[$index])) { + $dependencies[$index] = DefinitionResolver::ensureResolvable($value); + } + } + } + /** @psalm-var array $dependencies */ + } + + /** + * @throws InvalidConfigException + */ + private function isIntegerIndexed(array $arguments): bool + { + $hasStringIndex = false; + $hasIntegerIndex = false; + + foreach ($arguments as $index => $_argument) { + if (is_string($index)) { + $hasStringIndex = true; + if ($hasIntegerIndex) { + break; + } + } else { + $hasIntegerIndex = true; + if ($hasStringIndex) { + break; + } + } + } + if ($hasIntegerIndex && $hasStringIndex) { + throw new InvalidConfigException( + 'Arguments indexed both by name and by position are not allowed in the same array.' + ); + } + + return $hasIntegerIndex; } /** diff --git a/src/Infrastructure/ArrayDefinitionBuilder.php b/src/Infrastructure/ArrayDefinitionBuilder.php deleted file mode 100644 index 712622c..0000000 --- a/src/Infrastructure/ArrayDefinitionBuilder.php +++ /dev/null @@ -1,151 +0,0 @@ -getClass(); - $dependencies = DefinitionExtractor::getInstance()->fromClassName($class); - $constructorArguments = $definition->getConstructorArguments(); - - $this->injectArguments($dependencies, $constructorArguments); - - $resolved = DefinitionResolver::resolveArray($container, $referenceContainer, $dependencies); - - /** @psalm-suppress MixedMethodCall */ - $object = new $class(...array_values($resolved)); - - foreach ($definition->getMethodsAndProperties() as $item) { - /** @var mixed $value */ - [$type, $name, $value] = $item; - /** @var mixed */ - $value = DefinitionResolver::resolve($container, $referenceContainer, $value); - if ($type === ArrayDefinition::TYPE_METHOD) { - /** @var mixed */ - $setter = call_user_func_array([$object, $name], $value); - if ($setter instanceof $object) { - /** @var object */ - $object = $setter; - } - } elseif ($type === ArrayDefinition::TYPE_PROPERTY) { - $object->$name = $value; - } - } - - return $object; - } - - /** - * @psalm-param array $dependencies - * - * @throws InvalidConfigException - */ - private function injectArguments(array &$dependencies, array $arguments): void - { - $isIntegerIndexed = $this->isIntegerIndexed($arguments); - $dependencyIndex = 0; - $usedArguments = []; - $isVariadic = false; - foreach ($dependencies as $key => &$value) { - if ($value instanceof ParameterDefinition && $value->isVariadic()) { - $isVariadic = true; - } - $index = $isIntegerIndexed ? $dependencyIndex : $key; - if (array_key_exists($index, $arguments)) { - $value = DefinitionResolver::ensureResolvable($arguments[$index]); - $usedArguments[$index] = 1; - } - $dependencyIndex++; - } - unset($value); - if ($isVariadic) { - /** @var mixed $value */ - foreach ($arguments as $index => $value) { - if (!isset($usedArguments[$index])) { - $dependencies[$index] = DefinitionResolver::ensureResolvable($value); - } - } - } - /** @psalm-var array $dependencies */ - } - - /** - * @throws InvalidConfigException - */ - private function isIntegerIndexed(array $arguments): bool - { - $hasStringIndex = false; - $hasIntegerIndex = false; - - foreach ($arguments as $index => $_argument) { - if (is_string($index)) { - $hasStringIndex = true; - if ($hasIntegerIndex) { - break; - } - } else { - $hasIntegerIndex = true; - if ($hasStringIndex) { - break; - } - } - } - if ($hasIntegerIndex && $hasStringIndex) { - throw new InvalidConfigException( - 'Arguments indexed both by name and by position are not allowed in the same array.' - ); - } - - return $hasIntegerIndex; - } -}