comparison vendor/psy/psysh/src/Psy/Context.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 /*
4 * This file is part of Psy Shell.
5 *
6 * (c) 2012-2017 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 /**
15 * The Shell execution context.
16 *
17 * This class encapsulates the current variables, most recent return value and
18 * exception, and the current namespace.
19 */
20 class Context
21 {
22 private static $specialNames = array('_', '_e', '__out', '__psysh__', 'this');
23
24 // Whitelist a very limited number of command-scope magic variable names.
25 // This might be a bad idea, but future me can sort it out.
26 private static $commandScopeNames = array(
27 '__function', '__method', '__class', '__namespace', '__file', '__line', '__dir',
28 );
29
30 private $scopeVariables = array();
31 private $commandScopeVariables = array();
32 private $returnValue;
33 private $lastException;
34 private $lastStdout;
35 private $boundObject;
36
37 /**
38 * Get a context variable.
39 *
40 * @throws InvalidArgumentException If the variable is not found in the current context
41 *
42 * @param string $name
43 *
44 * @return mixed
45 */
46 public function get($name)
47 {
48 switch ($name) {
49 case '_':
50 return $this->returnValue;
51
52 case '_e':
53 if (isset($this->lastException)) {
54 return $this->lastException;
55 }
56 break;
57
58 case '__out':
59 if (isset($this->lastStdout)) {
60 return $this->lastStdout;
61 }
62 break;
63
64 case 'this':
65 if (isset($this->boundObject)) {
66 return $this->boundObject;
67 }
68 break;
69
70 case '__function':
71 case '__method':
72 case '__class':
73 case '__namespace':
74 case '__file':
75 case '__line':
76 case '__dir':
77 if (array_key_exists($name, $this->commandScopeVariables)) {
78 return $this->commandScopeVariables[$name];
79 }
80 break;
81
82 default:
83 if (array_key_exists($name, $this->scopeVariables)) {
84 return $this->scopeVariables[$name];
85 }
86 break;
87 }
88
89 throw new \InvalidArgumentException('Unknown variable: $' . $name);
90 }
91
92 /**
93 * Get all defined variables.
94 *
95 * @return array
96 */
97 public function getAll()
98 {
99 return array_merge($this->scopeVariables, $this->getSpecialVariables());
100 }
101
102 /**
103 * Get all defined magic variables: $_, $_e, $__out, $__class, $__file, etc.
104 *
105 * @return array
106 */
107 public function getSpecialVariables()
108 {
109 $vars = array(
110 '_' => $this->returnValue,
111 );
112
113 if (isset($this->lastException)) {
114 $vars['_e'] = $this->lastException;
115 }
116
117 if (isset($this->lastStdout)) {
118 $vars['__out'] = $this->lastStdout;
119 }
120
121 if (isset($this->boundObject)) {
122 $vars['this'] = $this->boundObject;
123 }
124
125 return array_merge($vars, $this->commandScopeVariables);
126 }
127
128 /**
129 * Set all scope variables.
130 *
131 * This method does *not* set any of the magic variables: $_, $_e, $__out,
132 * $__class, $__file, etc.
133 *
134 * @param array $vars
135 */
136 public function setAll(array $vars)
137 {
138 foreach (self::$specialNames as $key) {
139 unset($vars[$key]);
140 }
141
142 foreach (self::$commandScopeNames as $key) {
143 unset($vars[$key]);
144 }
145
146 $this->scopeVariables = $vars;
147 }
148
149 /**
150 * Set the most recent return value.
151 *
152 * @param mixed $value
153 */
154 public function setReturnValue($value)
155 {
156 $this->returnValue = $value;
157 }
158
159 /**
160 * Get the most recent return value.
161 *
162 * @return mixed
163 */
164 public function getReturnValue()
165 {
166 return $this->returnValue;
167 }
168
169 /**
170 * Set the most recent Exception.
171 *
172 * @param \Exception $e
173 */
174 public function setLastException(\Exception $e)
175 {
176 $this->lastException = $e;
177 }
178
179 /**
180 * Get the most recent Exception.
181 *
182 * @throws InvalidArgumentException If no Exception has been caught
183 *
184 * @return null|Exception
185 */
186 public function getLastException()
187 {
188 if (!isset($this->lastException)) {
189 throw new \InvalidArgumentException('No most-recent exception');
190 }
191
192 return $this->lastException;
193 }
194
195 /**
196 * Set the most recent output from evaluated code.
197 *
198 * @param string $lastStdout
199 */
200 public function setLastStdout($lastStdout)
201 {
202 $this->lastStdout = $lastStdout;
203 }
204
205 /**
206 * Get the most recent output from evaluated code.
207 *
208 * @throws InvalidArgumentException If no output has happened yet
209 *
210 * @return null|string
211 */
212 public function getLastStdout()
213 {
214 if (!isset($this->lastStdout)) {
215 throw new \InvalidArgumentException('No most-recent output');
216 }
217
218 return $this->lastStdout;
219 }
220
221 /**
222 * Set the bound object ($this variable) for the interactive shell.
223 *
224 * @param object|null $boundObject
225 */
226 public function setBoundObject($boundObject)
227 {
228 $this->boundObject = is_object($boundObject) ? $boundObject : null;
229 }
230
231 /**
232 * Get the bound object ($this variable) for the interactive shell.
233 *
234 * @return object|null
235 */
236 public function getBoundObject()
237 {
238 return $this->boundObject;
239 }
240
241 /**
242 * Set command-scope magic variables: $__class, $__file, etc.
243 *
244 * @param array $commandScopeVariables
245 */
246 public function setCommandScopeVariables(array $commandScopeVariables)
247 {
248 $vars = array();
249 foreach ($commandScopeVariables as $key => $value) {
250 // kind of type check
251 if (is_scalar($value) && in_array($key, self::$commandScopeNames)) {
252 $vars[$key] = $value;
253 }
254 }
255
256 $this->commandScopeVariables = $vars;
257 }
258
259 /**
260 * Get command-scope magic variables: $__class, $__file, etc.
261 *
262 * @return array
263 */
264 public function getCommandScopeVariables()
265 {
266 return $this->commandScopeVariables;
267 }
268
269 /**
270 * Get unused command-scope magic variables names: __class, __file, etc.
271 *
272 * This is used by the shell to unset old command-scope variables after a
273 * new batch is set.
274 *
275 * @return array Array of unused variable names
276 */
277 public function getUnusedCommandScopeVariableNames()
278 {
279 return array_diff(self::$commandScopeNames, array_keys($this->commandScopeVariables));
280 }
281
282 /**
283 * Check whether a variable name is a magic variable.
284 *
285 * @param string $name
286 *
287 * @return bool
288 */
289 public static function isSpecialVariableName($name)
290 {
291 return in_array($name, self::$specialNames) || in_array($name, self::$commandScopeNames);
292 }
293 }