Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php
<?php

/*
 * This file is part of Psy Shell.
 *
 * (c) 2012-2020 Justin Hileman
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Psy\ExecutionLoop;

use
Psy\Exception\ParseErrorException;
use
Psy\ParserFactory;
use
Psy\Shell;

/**
 * A runkit-based code reloader, which is pretty much magic.
 */
class RunkitReloader extends AbstractListener
{
    private
$parser;
    private
$timestamps = [];

   
/**
     * Only enabled if Runkit is installed.
     *
     * @return bool
     */
   
public static function isSupported()
    {
        return \
extension_loaded('runkit');
    }

   
/**
     * Construct a Runkit Reloader.
     *
     * @todo Pass in Parser Factory instance for dependency injection?
     */
   
public function __construct()
    {
       
$parserFactory = new ParserFactory();
       
$this->parser = $parserFactory->createParser();
    }

   
/**
     * Reload code on input.
     *
     * @param Shell  $shell
     * @param string $input
     */
   
public function onInput(Shell $shell, $input)
    {
       
$this->reload($shell);
    }

   
/**
     * Look through included files and update anything with a new timestamp.
     *
     * @param Shell $shell
     */
   
private function reload(Shell $shell)
    {
        \
clearstatcache();
       
$modified = [];

        foreach (\
get_included_files() as $file) {
           
$timestamp = \filemtime($file);

            if (!isset(
$this->timestamps[$file])) {
               
$this->timestamps[$file] = $timestamp;
                continue;
            }

            if (
$this->timestamps[$file] === $timestamp) {
                continue;
            }

            if (!
$this->lintFile($file)) {
               
$msg = \sprintf('Modified file "%s" could not be reloaded', $file);
               
$shell->writeException(new ParseErrorException($msg));
                continue;
            }

           
$modified[] = $file;
           
$this->timestamps[$file] = $timestamp;
        }

       
// switch (count($modified)) {
        //     case 0:
        //         return;

        //     case 1:
        //         printf("Reloading modified file: \"%s\"\n", str_replace(getcwd(), '.', $file));
        //         break;

        //     default:
        //         printf("Reloading %d modified files\n", count($modified));
        //         break;
        // }

       
foreach ($modified as $file) {
           
runkit_import($file, (
               
RUNKIT_IMPORT_FUNCTIONS |
               
RUNKIT_IMPORT_CLASSES |
               
RUNKIT_IMPORT_CLASS_METHODS |
               
RUNKIT_IMPORT_CLASS_CONSTS |
               
RUNKIT_IMPORT_CLASS_PROPS |
               
RUNKIT_IMPORT_OVERRIDE
           
));
        }
    }

   
/**
     * Should this file be re-imported?
     *
     * Use PHP-Parser to ensure that the file is valid PHP.
     *
     * @param string $file
     *
     * @return bool
     */
   
private function lintFile($file)
    {
       
// first try to parse it
       
try {
           
$this->parser->parse(\file_get_contents($file));
        } catch (\
Exception $e) {
            return
false;
        }

        return
true;
    }
}