<commit_before><?php

namespace Ray\Di;

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Cache\ApcCache;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\FilesystemCache;
use Ray\Aop\Compiler;
use SplObjectStorage;

/**
 * This file is part of the BEAR.Package package
 *
 * @package BEAR.Package
 * @license http://opensource.org/licenses/bsd-license.php BSD
 */
class CacheInjector implements InstanceInterface
{
    /**
     * @var \Doctrine\Common\Cache\Cache
     */
    private $cache;

    /**
     * @var callable
     */
    private $injector;

    /**
     * @var callable
     */
    private $postInject;

    private $tmpDir;

    /**
     * @param callable $injector
     * @param callable $postInject
     * @param          $key
     * @param Cache    $cache
     * @param          $tmpDir
     */
    public function __construct(
        callable $injector,
        callable $postInject,
        $key,
        Cache $cache = null,
        $tmpDir = null
    ) {
        $this->injector = $injector;
        $this->postInject = $postInject;
        if (is_null($cache)) {
            $cache = function_exists('apc_fetch') ? new ApcCache : new FilesystemCache($this->tmpDir);
        }
        $cache->setNamespace($key);
        $this->cache = $cache;
        $this->tmpDir = $tmpDir ?: sys_get_temp_dir();
    }

    /**
     * Return injected instance using cache
     *
     * @param string $class class or interface
     *
     * @return object
     */
    public function getInstance($class)
    {
        list($instance, $preDestroy, $classDir) =
            $this->cache->contains($class) ?
                $this->cache->fetch($class) :
                $this->createInstance($class);

        $this->registerAopFileLoader($classDir);

        register_shutdown_function(
            function () use ($preDestroy) {
                $this->notifyPreShutdown($preDestroy);
            }
        );

        return $instance;
    }

    /**
     * Register generated aop file auto loader
     *
     * @param $classDir
     */
    private function registerAopFileLoader($classDir)
    {
        spl_autoload_register(
            function ($class) use ($classDir) {
                $file = $classDir . DIRECTORY_SEPARATOR . $class . '.php';
                if (file_exists($file)) {
                    /** @noinspection PhpIncludeInspection */
                    include $file;
                }
            }
        );
    }
    /**
     * Return injected instance and $preDestroy
     *
     * @param $class
     *
     * @return array [object $instance, SplObjectStorage $preDestroy]
     */
    private function createInstance($class)
    {
        $injector = call_user_func($this->injector);
        /** @var $injector Injector */
        $this->removeAopFiles($this->tmpDir);
        $instance = $injector->getInstance($class);
        $preDestroy = $injector->getPreDestroyObjects();
        $this->cache->save($class, [$instance, $preDestroy, $injector->getAopClassDir()]);

        // post injection
        call_user_func($this->postInject, [$instance, $injector]);

        return [$instance, $preDestroy, $injector->getAopClassDir()];
    }


    /**
     * Clear generated aop files
     *
     * @param $dir
     */
    private function removeAopFiles($dir)
    {
        foreach (glob($dir . '/*Aop.php') as $file) {
            unlink($file);
        }
    }

    /**
     * Notify pre-destroy
     *
     * @param SplObjectStorage $preDestroyObjects
     *
     * @return void
     */
    private function notifyPreShutdown(SplObjectStorage $preDestroyObjects)
    {
        $preDestroyObjects->rewind();
        while ($preDestroyObjects->valid()) {
            $object = $preDestroyObjects->current();
            $method = $preDestroyObjects->getInfo();
            $object->$method();
            $preDestroyObjects->next();
        }
    }
}
<commit_msg>fix post injection call<commit_after><?php

namespace Ray\Di;

use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Cache\ApcCache;
use Doctrine\Common\Cache\Cache;
use Doctrine\Common\Cache\FilesystemCache;
use Ray\Aop\Compiler;
use SplObjectStorage;

/**
 * This file is part of the BEAR.Package package
 *
 * @package BEAR.Package
 * @license http://opensource.org/licenses/bsd-license.php BSD
 */
class CacheInjector implements InstanceInterface
{
    /**
     * @var \Doctrine\Common\Cache\Cache
     */
    private $cache;

    /**
     * @var callable
     */
    private $injector;

    /**
     * @var callable
     */
    private $postInject;

    private $tmpDir;

    /**
     * @param callable $injector
     * @param callable $postInject
     * @param          $key
     * @param Cache    $cache
     * @param          $tmpDir
     *
     * $injector = function() {return Injector::create([new Module]);}
     * $postInject = function($instance, InjectorInterface $injector){};
     */
    public function __construct(
        callable $injector,
        callable $postInject,
        $key,
        Cache $cache = null,
        $tmpDir = null
    ) {
        $this->injector = $injector;
        $this->postInject = $postInject;
        if (is_null($cache)) {
            $cache = function_exists('apc_fetch') ? new ApcCache : new FilesystemCache($this->tmpDir);
        }
        $cache->setNamespace($key);
        $this->cache = $cache;
        $this->tmpDir = $tmpDir ?: sys_get_temp_dir();
    }

    /**
     * Return injected instance using cache
     *
     * @param string $class class or interface
     *
     * @return object
     */
    public function getInstance($class)
    {
        list($instance, $preDestroy, $classDir) =
            $this->cache->contains($class) ?
                $this->cache->fetch($class) :
                $this->createInstance($class);

        $this->registerAopFileLoader($classDir);

        register_shutdown_function(
            function () use ($preDestroy) {
                $this->notifyPreShutdown($preDestroy);
            }
        );

        return $instance;
    }

    /**
     * Register generated aop file auto loader
     *
     * @param $classDir
     */
    private function registerAopFileLoader($classDir)
    {
        spl_autoload_register(
            function ($class) use ($classDir) {
                $file = $classDir . DIRECTORY_SEPARATOR . $class . '.php';
                if (file_exists($file)) {
                    /** @noinspection PhpIncludeInspection */
                    include $file;
                }
            }
        );
    }
    /**
     * Return injected instance and $preDestroy
     *
     * @param $class
     *
     * @return array [object $instance, SplObjectStorage $preDestroy]
     */
    private function createInstance($class)
    {
        $injector = call_user_func($this->injector);
        /** @var $injector Injector */
        $this->removeAopFiles($this->tmpDir);
        $instance = $injector->getInstance($class);
        $preDestroy = $injector->getPreDestroyObjects();
        $this->cache->save($class, [$instance, $preDestroy, $injector->getAopClassDir()]);

        // post injection
        call_user_func_array($this->postInject, [$instance, $injector]);

        return [$instance, $preDestroy, $injector->getAopClassDir()];
    }


    /**
     * Clear generated aop files
     *
     * @param $dir
     */
    private function removeAopFiles($dir)
    {
        foreach (glob($dir . '/*Aop.php') as $file) {
            unlink($file);
        }
    }

    /**
     * Notify pre-destroy
     *
     * @param SplObjectStorage $preDestroyObjects
     *
     * @return void
     */
    private function notifyPreShutdown(SplObjectStorage $preDestroyObjects)
    {
        $preDestroyObjects->rewind();
        while ($preDestroyObjects->valid()) {
            $object = $preDestroyObjects->current();
            $method = $preDestroyObjects->getInfo();
            $object->$method();
            $preDestroyObjects->next();
        }
    }
}

{'fraction_non_alphanumeric': 0.13059190031152648, 'fraction_numerical': 0.0, 'mean_word_length': 2.020700037636432, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 61, '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': '748574', 'n_tokens_mistral': 2360, 'n_tokens_neox': 2312, 'n_words': 454}