<commit_before><?php

namespace Assembly\Container;

use Assembly\InstanceDefinition;
use Interop\Container\ContainerInterface;
use Interop\Container\Definition\AliasDefinitionInterface;
use Interop\Container\Definition\DefinitionInterface;
use Interop\Container\Definition\DefinitionProviderInterface;
use Interop\Container\Definition\FactoryDefinitionInterface;
use Interop\Container\Definition\ParameterDefinitionInterface;
use Interop\Container\Definition\ReferenceInterface;

/**
 * Simple immutable container that can resolve standard definitions.
 */
class Container implements ContainerInterface
{
    /**
     * @var DefinitionInterface[]
     */
    private $definitions = [];

    /**
     * @var array
     */
    private $entries = [];

    /**
     * @param array $entries Container entries.
     */
    public function __construct(array $entries, array $providers = [])
    {
        $this->entries = $entries;
        foreach ($providers as $provider) {
            $this->addProvider($provider);
        }
    }

    public function get($id)
    {
        if (array_key_exists($id, $this->entries)) {
            return $this->entries[$id];
        }

        if (!isset($this->definitions[$id])) {
            throw EntryNotFound::fromId($id);
        }

        $this->entries[$id] = $this->resolveDefinition($this->definitions[$id], $id);

        return $this->entries[$id];
    }

    public function has($id)
    {
        return isset($this->definitions[$id]) || array_key_exists($id, $this->entries);
    }

    /**
     * Register a definition provider.
     */
    private function addProvider(DefinitionProviderInterface $definitionProvider)
    {
        foreach ($definitionProvider->getDefinitions() as $definition) {
            $this->definitions[$definition->getIdentifier()] = $definition;
        }
    }

    /**
     * Resolve a definition and return the resulting value.
     *
     * @param DefinitionInterface $definition
     * @return mixed
     * @throws UnsupportedDefinition
     * @throws EntryNotFound A dependency was not found.
     */
    private function resolveDefinition(DefinitionInterface $definition, $requestedId)
    {
        switch (true) {
            case $definition instanceof ParameterDefinitionInterface:
                return $definition->getValue();
            case $definition instanceof InstanceDefinition:
                $reflection = new \ReflectionClass($definition->getClassName());

                // Create the instance
                $constructorArguments = $definition->getConstructorArguments();
                $constructorArguments = array_map([$this, 'resolveReference'], $constructorArguments);
                $service = $reflection->newInstanceArgs($constructorArguments);

                // Set properties
                foreach ($definition->getPropertyAssignments() as $propertyAssignment) {
                    $propertyName = $propertyAssignment->getPropertyName();
                    $service->$propertyName = $this->resolveReference($propertyAssignment->getValue());
                }

                // Call methods
                foreach ($definition->getMethodCalls() as $methodCall) {
                    $methodArguments = $methodCall->getArguments();
                    $methodArguments = array_map([$this, 'resolveReference'], $methodArguments);
                    call_user_func_array([$service, $methodCall->getMethodName()], $methodArguments);
                }

                return $service;<commit_msg>Complete container Phpdoc<commit_after><?php

namespace Assembly\Container;

use Assembly\InstanceDefinition;
use Interop\Container\ContainerInterface;
use Interop\Container\Definition\AliasDefinitionInterface;
use Interop\Container\Definition\DefinitionInterface;
use Interop\Container\Definition\DefinitionProviderInterface;
use Interop\Container\Definition\FactoryDefinitionInterface;
use Interop\Container\Definition\ParameterDefinitionInterface;
use Interop\Container\Definition\ReferenceInterface;

/**
 * Simple immutable container that can resolve standard definitions.
 */
class Container implements ContainerInterface
{
    /**
     * @var DefinitionInterface[]
     */
    private $definitions = [];

    /**
     * @var array
     */
    private $entries = [];

    /**
     * @param array $entries Container entries.
     */
    public function __construct(array $entries, array $providers = [])
    {
        $this->entries = $entries;
        foreach ($providers as $provider) {
            $this->addProvider($provider);
        }
    }

    public function get($id)
    {
        if (array_key_exists($id, $this->entries)) {
            return $this->entries[$id];
        }

        if (!isset($this->definitions[$id])) {
            throw EntryNotFound::fromId($id);
        }

        $this->entries[$id] = $this->resolveDefinition($this->definitions[$id], $id);

        return $this->entries[$id];
    }

    public function has($id)
    {
        return isset($this->definitions[$id]) || array_key_exists($id, $this->entries);
    }

    /**
     * Register a definition provider.
     */
    private function addProvider(DefinitionProviderInterface $definitionProvider)
    {
        foreach ($definitionProvider->getDefinitions() as $definition) {
            $this->definitions[$definition->getIdentifier()] = $definition;
        }
    }

    /**
     * Resolve a definition and return the resulting value.
     *
     * @param DefinitionInterface $definition
     * @param string $requestedId
     * @return mixed
     * @throws UnsupportedDefinition
     * @throws EntryNotFound A dependency was not found.
     */
    private function resolveDefinition(DefinitionInterface $definition, $requestedId)
    {
        switch (true) {
            case $definition instanceof ParameterDefinitionInterface:
                return $definition->getValue();
            case $definition instanceof InstanceDefinition:
                $reflection = new \ReflectionClass($definition->getClassName());

                // Create the instance
                $constructorArguments = $definition->getConstructorArguments();
                $constructorArguments = array_map([$this, 'resolveReference'], $constructorArguments);
                $service = $reflection->newInstanceArgs($constructorArguments);

                // Set properties
                foreach ($definition->getPropertyAssignments() as $propertyAssignment) {
                    $propertyName = $propertyAssignment->getPropertyName();
                    $service->$propertyName = $this->resolveReference($propertyAssignment->getValue());
                }

                // Call methods
                foreach ($definition->getMethodCalls() as $methodCall) {
                    $methodArguments = $methodCall->getArguments();
                    $methodArguments = array_map([$this, 'resolveReference'], $methodArguments);
                    call_user_func_array([$service, $methodCall->getMethodName()], $methodArguments);
                }

                return $service;
{'fraction_non_alphanumeric': 0.11354019746121298, 'fraction_numerical': 0.0, 'mean_word_length': 2.617857142857143, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2983948', 'n_tokens_mistral': 1681, 'n_tokens_neox': 1633, 'n_words': 354}