annotate vendor/psy/psysh/src/Psy/Context.php @ 7:848c88cfe644

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