4 * This file is part of Psy Shell.
6 * (c) 2012-2018 Justin Hileman
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
15 * The Shell execution context.
17 * This class encapsulates the current variables, most recent return value and
18 * exception, and the current namespace.
22 private static $specialNames = ['_', '_e', '__out', '__psysh__', 'this'];
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 = [
27 '__function', '__method', '__class', '__namespace', '__file', '__line', '__dir',
30 private $scopeVariables = [];
31 private $commandScopeVariables = [];
33 private $lastException;
38 * Get a context variable.
40 * @throws InvalidArgumentException If the variable is not found in the current context
46 public function get($name)
50 return $this->returnValue;
53 if (isset($this->lastException)) {
54 return $this->lastException;
59 if (isset($this->lastStdout)) {
60 return $this->lastStdout;
65 if (isset($this->boundObject)) {
66 return $this->boundObject;
77 if (array_key_exists($name, $this->commandScopeVariables)) {
78 return $this->commandScopeVariables[$name];
83 if (array_key_exists($name, $this->scopeVariables)) {
84 return $this->scopeVariables[$name];
89 throw new \InvalidArgumentException('Unknown variable: $' . $name);
93 * Get all defined variables.
97 public function getAll()
99 return array_merge($this->scopeVariables, $this->getSpecialVariables());
103 * Get all defined magic variables: $_, $_e, $__out, $__class, $__file, etc.
107 public function getSpecialVariables()
110 '_' => $this->returnValue,
113 if (isset($this->lastException)) {
114 $vars['_e'] = $this->lastException;
117 if (isset($this->lastStdout)) {
118 $vars['__out'] = $this->lastStdout;
121 if (isset($this->boundObject)) {
122 $vars['this'] = $this->boundObject;
125 return array_merge($vars, $this->commandScopeVariables);
129 * Set all scope variables.
131 * This method does *not* set any of the magic variables: $_, $_e, $__out,
132 * $__class, $__file, etc.
136 public function setAll(array $vars)
138 foreach (self::$specialNames as $key) {
142 foreach (self::$commandScopeNames as $key) {
146 $this->scopeVariables = $vars;
150 * Set the most recent return value.
152 * @param mixed $value
154 public function setReturnValue($value)
156 $this->returnValue = $value;
160 * Get the most recent return value.
164 public function getReturnValue()
166 return $this->returnValue;
170 * Set the most recent Exception.
172 * @param \Exception $e
174 public function setLastException(\Exception $e)
176 $this->lastException = $e;
180 * Get the most recent Exception.
182 * @throws \InvalidArgumentException If no Exception has been caught
184 * @return null|\Exception
186 public function getLastException()
188 if (!isset($this->lastException)) {
189 throw new \InvalidArgumentException('No most-recent exception');
192 return $this->lastException;
196 * Set the most recent output from evaluated code.
198 * @param string $lastStdout
200 public function setLastStdout($lastStdout)
202 $this->lastStdout = $lastStdout;
206 * Get the most recent output from evaluated code.
208 * @throws \InvalidArgumentException If no output has happened yet
210 * @return null|string
212 public function getLastStdout()
214 if (!isset($this->lastStdout)) {
215 throw new \InvalidArgumentException('No most-recent output');
218 return $this->lastStdout;
222 * Set the bound object ($this variable) for the interactive shell.
224 * @param object|null $boundObject
226 public function setBoundObject($boundObject)
228 $this->boundObject = is_object($boundObject) ? $boundObject : null;
232 * Get the bound object ($this variable) for the interactive shell.
234 * @return object|null
236 public function getBoundObject()
238 return $this->boundObject;
242 * Set command-scope magic variables: $__class, $__file, etc.
244 * @param array $commandScopeVariables
246 public function setCommandScopeVariables(array $commandScopeVariables)
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;
256 $this->commandScopeVariables = $vars;
260 * Get command-scope magic variables: $__class, $__file, etc.
264 public function getCommandScopeVariables()
266 return $this->commandScopeVariables;
270 * Get unused command-scope magic variables names: __class, __file, etc.
272 * This is used by the shell to unset old command-scope variables after a
275 * @return array Array of unused variable names
277 public function getUnusedCommandScopeVariableNames()
279 return array_diff(self::$commandScopeNames, array_keys($this->commandScopeVariables));
283 * Check whether a variable name is a magic variable.
285 * @param string $name
289 public static function isSpecialVariableName($name)
291 return in_array($name, self::$specialNames) || in_array($name, self::$commandScopeNames);