<commit_before><?php
/**
 * <NAME>. Copyright 2013-2014 Silktide Ltd. All Rights Reserved.
 */
namespace Silktide\Syringe;
use Pimple\Container;
use Silktide\Syringe\Exception\ConfigException;
use Silktide\Syringe\Exception\LoaderException;
use Silktide\Syringe\Loader\LoaderInterface;

/**
 * ContainerBuilder parses configuration files and build a Pimple Container
 */
class ContainerBuilder {

    /**
     * The character that identifies a service
     * e.g. "@service"
     */
    const SERVICE_CHAR = "@";

    /**
     * The character that identifies the boundaries of a parameter
     * e.g. "%parameter%"
     */
    const PARAMETER_CHAR = "%";

    /**
     * @var array
     */
    protected $loaders = [];

    /**
     * @var array
     */
    protected $configPaths = [];

    /**
     * @var array
     */
    protected $configFiles = [];

    /**
     * @var ReferenceResolverInterface
     */
    protected $referenceResolver;

    /**
     * @var array
     */
    protected $abstractDefinitions = [];

    /**
     * @var array
     */
    protected $parameterNames = [];

    /**
     * @param ReferenceResolverInterface $resolver
     * @param array $configPaths
     */
    public function __construct(ReferenceResolverInterface $resolver, array $configPaths = [])
    {
        $this->referenceResolver = $resolver;

        $this->configPaths = ["/"];
        foreach ($configPaths as $path) {
            $this->addConfigPath($path);
        }
    }

    /**
     * Add a directory to search in when loading configuration files
     *
     * @param string $path
     * @throws Exception\LoaderException
     */
    public function addConfigPath($path)
    {
        if (!is_dir($path)) {
            throw new LoaderException(sprintf("The config path '%s' is not a valid directory", $path));
        }
        if ($path[strlen($path) - 1] != "/") {
            $path .= "/";
        }
        $this->configPaths[] = $path;
    }

    /**
     * @param LoaderInterface $loader
     */
    public function addLoader(LoaderInterface $loader)
    {
        $this->loaders[] = $loader;
    }

    /**
     * @param string $name
     */
    public function removeLoader($name)
    {
        foreach ($this->loaders as $i => $loader) {
            /** @var LoaderInterface $loader */
            if ($name == $loader->getName()) {
                unset($this->loaders[$i]);
            }
        }
    }

    /**
     * Remove the loader that supports the specified file
     *
     * @param string $file
     */
    public function removeLoaderByFile($file)
    {
        foreach ($this->loaders as $i => $loader) {
            /** @var LoaderInterface $loader */
            if ($loader->supports($file)) {
                unset($this->loaders[$i]);
            }
        }
    }

    /**
     * Queue a config file to be processed
     *
     * @param string $file
     * @param string|null $alias
     * @throws Exception\LoaderException
     */
    public function addConfigFile($file, $alias = null) {
        foreach ($this->configPaths as $path) {
            $filePath = $path . $file;
            if (file_exists($filePath)) {
                if (!is_string($alias)) {
                    $this->configFiles[] = $filePath;
                } else {
                    $this->configFiles[$alias] = $filePath;
                }
                return;
            }
        }
        throw new LoaderException(sprintf("The config file '%s' does not exist in any of the configured paths", $file));
    }

    /**
     * @param array $files
     */
    public function addConfigFiles(array $files)
    {
        foreach ($files as $alias => $file) {
            $this->addConfigFile($file, $alias);
        }
    }

    /**
     * @return Container
     */
    public function createContainer()
    {
        $container = new Container();
        
        foreach ($this->configFiles as $alias => $file) {
            if (!is_string($alias)) {
                // empty alias for numeric keys
                $alias = "";
            }<commit_msg>Allow subclasses of Pimple\Container to be created<commit_after><?php
/**
 * <NAME>. Copyright 2013-2014 Silktide Ltd. All Rights Reserved.
 */
namespace Silktide\Syringe;
use Pimple\Container;
use Silktide\Syringe\Exception\ConfigException;
use Silktide\Syringe\Exception\LoaderException;
use Silktide\Syringe\Loader\LoaderInterface;

/**
 * ContainerBuilder parses configuration files and build a Pimple Container
 */
class ContainerBuilder {

    /**
     * The character that identifies a service
     * e.g. "@service"
     */
    const SERVICE_CHAR = "@";

    /**
     * The character that identifies the boundaries of a parameter
     * e.g. "%parameter%"
     */
    const PARAMETER_CHAR = "%";

    /**
     * Default class name for the container
     */
    const DEFAULT_CONTAINER_CLASS = "Pimple\\Container";

    /**
     * Contains the class name for the container we want to create
     *
     * @var string
     */
    protected $containerClass = self::DEFAULT_CONTAINER_CLASS;

    /**
     * @var array
     */
    protected $loaders = [];

    /**
     * @var array
     */
    protected $configPaths = [];

    /**
     * @var array
     */
    protected $configFiles = [];

    /**
     * @var ReferenceResolverInterface
     */
    protected $referenceResolver;

    /**
     * @var array
     */
    protected $abstractDefinitions = [];

    /**
     * @var array
     */
    protected $parameterNames = [];

    /**
     * @param ReferenceResolverInterface $resolver
     * @param array $configPaths
     */
    public function __construct(ReferenceResolverInterface $resolver, array $configPaths = [])
    {
        $this->referenceResolver = $resolver;

        $this->configPaths = ["/"];
        foreach ($configPaths as $path) {
            $this->addConfigPath($path);
        }
    }

    public function setContainerClass($containerClass)
    {
        // check existence
        if (!class_exists($containerClass)) {
            throw new ConfigException(sprintf("The container class '%s' does not exist", $containerClass));
        }
        // check the class is a container
        if ($containerClass != self::DEFAULT_CONTAINER_CLASS && !is_subclass_of($containerClass, self::DEFAULT_CONTAINER_CLASS)) {
            throw new ConfigException(sprintf("The class '%s' is not a subclass of '%s'", $containerClass, self::DEFAULT_CONTAINER_CLASS));
        }

        $this->containerClass = $containerClass;
    }

    /**
     * Add a directory to search in when loading configuration files
     *
     * @param string $path
     * @throws Exception\LoaderException
     */
    public function addConfigPath($path)
    {
        if (!is_dir($path)) {
            throw new LoaderException(sprintf("The config path '%s' is not a valid directory", $path));
        }
        if ($path[strlen($path) - 1] != "/") {
            $path .= "/";
        }
        $this->configPaths[] = $path;
    }

    /**
     * @param LoaderInterface $loader
     */
    public function addLoader(LoaderInterface $loader)
    {
        $this->loaders[] = $loader;
    }

    /**
     * @param string $name
     */
    public function removeLoader($name)
    {
        foreach ($this->loaders as $i => $loader) {
            /** @var LoaderInterface $loader */
            if ($name == $loader->getName()) {
                unset($this->loaders[$i]);
            }
        }
    }

    /**
     * Remove the loader that supports the specified file
     *
     * @param string $file
     */
    public function removeLoaderByFile($file)
    {
        foreach ($this->loaders as $i => $loader) {
            /** @var LoaderInterface $loader */
            if ($loader->supports($file)) {
                unset($this->loaders[$i]);
            }
        }
    }

    /**
     * Queue a config file to be processed
     *
     * @param string $file
     * @param string|null $alias
     * @throws Exception\LoaderException
     */
    public function addConfigFile($file, $alias = null) {
        foreach ($this->configPaths as $path) {
            $filePath = $path . $file;
            if (file_exists($filePath)) {
                if (!is_string($alias)) {
                    $this->configFiles[] = $filePath;
                } else {
                    $this->configFiles[$alias] = $filePath;
                }
                return;
            }
        }
        throw new LoaderException(sprintf("The config file '%s' does not exist in any of the configured paths", $file));
    }

    /**
     * @param array $files
     */
    public function addConfigFiles(array $files)
    {
        foreach ($files as $alias => $file) {
            $this->addConfigFile($file, $alias);
        }
    }

    /**
     * @return Container
     */
    public function createContainer()
    {
        $container = new $this->containerClass();
        
        foreach ($this->configFiles as $alias => $file) {
            if (!is_string($alias)) {
                // empty alias for numeric keys
                $alias = "";
            }
{'fraction_non_alphanumeric': 0.13067807768268597, 'fraction_numerical': 0.0019749835418038184, 'mean_word_length': 1.869058860560277, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 47, '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': '2939648', 'n_tokens_mistral': 2549, 'n_tokens_neox': 2470, 'n_words': 624}