Version 1
[yaffs-website] / vendor / psy / psysh / src / Psy / ExecutionLoop / Loop.php
diff --git a/vendor/psy/psysh/src/Psy/ExecutionLoop/Loop.php b/vendor/psy/psysh/src/Psy/ExecutionLoop/Loop.php
new file mode 100644 (file)
index 0000000..79c3109
--- /dev/null
@@ -0,0 +1,186 @@
+<?php
+
+/*
+ * This file is part of Psy Shell.
+ *
+ * (c) 2012-2017 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\Configuration;
+use Psy\Exception\BreakException;
+use Psy\Exception\ErrorException;
+use Psy\Exception\ThrowUpException;
+use Psy\Exception\TypeErrorException;
+use Psy\Shell;
+
+/**
+ * The Psy Shell execution loop.
+ */
+class Loop
+{
+    const NOOP_INPUT = 'return null;';
+
+    /**
+     * Loop constructor.
+     *
+     * The non-forking loop doesn't have much use for Configuration, so we'll
+     * just ignore it.
+     *
+     * @param Configuration $config
+     */
+    public function __construct(Configuration $config)
+    {
+        // don't need this
+    }
+
+    /**
+     * Run the execution loop.
+     *
+     * @throws ThrowUpException if thrown by the `throw-up` command
+     *
+     * @param Shell $shell
+     */
+    public function run(Shell $shell)
+    {
+        $loop = function ($__psysh__) {
+            // Load user-defined includes
+            set_error_handler(array($__psysh__, 'handleError'));
+            try {
+                foreach ($__psysh__->getIncludes() as $__psysh_include__) {
+                    include $__psysh_include__;
+                }
+            } catch (\Exception $_e) {
+                $__psysh__->writeException($_e);
+            }
+            restore_error_handler();
+            unset($__psysh_include__);
+
+            extract($__psysh__->getScopeVariables(false));
+
+            do {
+                $__psysh__->beforeLoop();
+                $__psysh__->setScopeVariables(get_defined_vars());
+
+                try {
+                    // read a line, see if we should eval
+                    $__psysh__->getInput();
+
+                    // evaluate the current code buffer
+                    ob_start(
+                        array($__psysh__, 'writeStdout'),
+                        version_compare(PHP_VERSION, '5.4', '>=') ? 1 : 2
+                    );
+
+                    // Let PsySH inject some magic variables back into the
+                    // shell scope... things like $__class, and $__file set by
+                    // reflection commands
+                    extract($__psysh__->getSpecialScopeVariables(false));
+
+                    // And unset any magic variables which are no longer needed
+                    foreach ($__psysh__->getUnusedCommandScopeVariableNames() as $__psysh_var_name__) {
+                        unset($$__psysh_var_name__, $__psysh_var_name__);
+                    }
+
+                    set_error_handler(array($__psysh__, 'handleError'));
+                    $_ = eval($__psysh__->flushCode() ?: Loop::NOOP_INPUT);
+                    restore_error_handler();
+
+                    ob_end_flush();
+
+                    $__psysh__->writeReturnValue($_);
+                } catch (BreakException $_e) {
+                    restore_error_handler();
+                    if (ob_get_level() > 0) {
+                        ob_end_clean();
+                    }
+                    $__psysh__->writeException($_e);
+
+                    return;
+                } catch (ThrowUpException $_e) {
+                    restore_error_handler();
+                    if (ob_get_level() > 0) {
+                        ob_end_clean();
+                    }
+                    $__psysh__->writeException($_e);
+
+                    throw $_e;
+                } catch (\TypeError $_e) {
+                    restore_error_handler();
+                    if (ob_get_level() > 0) {
+                        ob_end_clean();
+                    }
+                    $__psysh__->writeException(TypeErrorException::fromTypeError($_e));
+                } catch (\Error $_e) {
+                    restore_error_handler();
+                    if (ob_get_level() > 0) {
+                        ob_end_clean();
+                    }
+                    $__psysh__->writeException(ErrorException::fromError($_e));
+                } catch (\Exception $_e) {
+                    restore_error_handler();
+                    if (ob_get_level() > 0) {
+                        ob_end_clean();
+                    }
+                    $__psysh__->writeException($_e);
+                }
+
+                $__psysh__->afterLoop();
+            } while (true);
+        };
+
+        // bind the closure to $this from the shell scope variables...
+        if (self::bindLoop()) {
+            $that = $shell->getBoundObject();
+            if (is_object($that)) {
+                $loop = $loop->bindTo($that, get_class($that));
+            } else {
+                $loop = $loop->bindTo(null, null);
+            }
+        }
+
+        $loop($shell);
+    }
+
+    /**
+     * A beforeLoop callback.
+     *
+     * This is executed at the start of each loop iteration. In the default
+     * (non-forking) loop implementation, this is a no-op.
+     */
+    public function beforeLoop()
+    {
+        // no-op
+    }
+
+    /**
+     * A afterLoop callback.
+     *
+     * This is executed at the end of each loop iteration. In the default
+     * (non-forking) loop implementation, this is a no-op.
+     */
+    public function afterLoop()
+    {
+        // no-op
+    }
+
+    /**
+     * Decide whether to bind the execution loop.
+     *
+     * @return bool
+     */
+    protected static function bindLoop()
+    {
+        // skip binding on HHVM <= 3.5.0
+        // see https://github.com/facebook/hhvm/issues/1203
+        if (defined('HHVM_VERSION')) {
+            return version_compare(HHVM_VERSION, '3.5.0', '>=');
+        }
+
+        return version_compare(PHP_VERSION, '5.4', '>=');
+    }
+}