5b8238cf632364ac80f3eb5a9b09aaf3fc656380
[yaffs-website] / vendor / psy / psysh / src / ExecutionLoopClosure.php
1 <?php
2
3 /*
4  * This file is part of Psy Shell.
5  *
6  * (c) 2012-2018 Justin Hileman
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Psy;
13
14 use Psy\Exception\BreakException;
15 use Psy\Exception\ErrorException;
16 use Psy\Exception\ThrowUpException;
17 use Psy\Exception\TypeErrorException;
18
19 /**
20  * The Psy Shell's execution loop scope.
21  *
22  * @todo Once we're on PHP 5.5, we can switch ExecutionClosure to a generator
23  * and get rid of the duplicate closure implementations :)
24  */
25 class ExecutionLoopClosure extends ExecutionClosure
26 {
27     /**
28      * @param Shell $__psysh__
29      */
30     public function __construct(Shell $__psysh__)
31     {
32         $this->setClosure($__psysh__, function () use ($__psysh__) {
33             // Restore execution scope variables
34             \extract($__psysh__->getScopeVariables(false));
35
36             do {
37                 $__psysh__->beforeLoop();
38
39                 try {
40                     $__psysh__->getInput();
41
42                     try {
43                         // Pull in any new execution scope variables
44                         if ($__psysh__->getLastExecSuccess()) {
45                             \extract($__psysh__->getScopeVariablesDiff(\get_defined_vars()));
46                         }
47
48                         // Buffer stdout; we'll need it later
49                         \ob_start([$__psysh__, 'writeStdout'], 1);
50
51                         // Convert all errors to exceptions
52                         \set_error_handler([$__psysh__, 'handleError']);
53
54                         // Evaluate the current code buffer
55                         $_ = eval($__psysh__->onExecute($__psysh__->flushCode() ?: ExecutionClosure::NOOP_INPUT));
56                     } catch (\Throwable $_e) {
57                         // Clean up on our way out.
58                         \restore_error_handler();
59                         if (\ob_get_level() > 0) {
60                             \ob_end_clean();
61                         }
62
63                         throw $_e;
64                     } catch (\Exception $_e) {
65                         // Clean up on our way out.
66                         \restore_error_handler();
67                         if (\ob_get_level() > 0) {
68                             \ob_end_clean();
69                         }
70
71                         throw $_e;
72                     }
73
74                     // Won't be needing this anymore
75                     \restore_error_handler();
76
77                     // Flush stdout (write to shell output, plus save to magic variable)
78                     \ob_end_flush();
79
80                     // Save execution scope variables for next time
81                     $__psysh__->setScopeVariables(\get_defined_vars());
82
83                     $__psysh__->writeReturnValue($_);
84                 } catch (BreakException $_e) {
85                     $__psysh__->writeException($_e);
86
87                     return;
88                 } catch (ThrowUpException $_e) {
89                     $__psysh__->writeException($_e);
90
91                     throw $_e;
92                 } catch (\TypeError $_e) {
93                     $__psysh__->writeException(TypeErrorException::fromTypeError($_e));
94                 } catch (\Error $_e) {
95                     $__psysh__->writeException(ErrorException::fromError($_e));
96                 } catch (\Exception $_e) {
97                     $__psysh__->writeException($_e);
98                 }
99
100                 $__psysh__->afterLoop();
101             } while (true);
102         });
103     }
104 }