/** * Main runner method * * @param string[] args */ public static function main(array $args) { // Parse args $api = new RestClient('http://builds.planet-xp.net/'); $action = null; $cat = null; for ($i = 0, $s = sizeof($args); $i < $s; $i++) { if ('-?' === $args[$i] || '--help' === $args[$i]) { break; } else { if ('-a' === $args[$i]) { $api->setBase($args[++$i]); } else { if ('-v' === $args[$i]) { $cat = create(new LogCategory('console'))->withAppender(new ColoredConsoleAppender()); } else { if ('-' === $args[$i][0]) { Console::$err->writeLine('*** Unknown argument ', $args[$i]); return 128; } else { $action = $args[$i]; // First non-option is the action name break; } } } } } if (null === $action) { Console::$err->writeLine(self::textOf(\lang\XPClass::forName(\xp::nameOf(__CLASS__))->getComment())); return 1; } try { $class = \lang\reflect\Package::forName('xp.install')->loadClass(ucfirst($action) . 'Action'); } catch (\lang\ClassNotFoundException $e) { Console::$err->writeLine('*** No such action "' . $action . '"'); return 2; } // Show help if (in_array('-?', $args) || in_array('--help', $args)) { Console::$out->writeLine(self::textOf($class->getComment())); return 3; } // Perform action $instance = $class->newInstance($api); $instance->setTrace($cat); try { return $instance->perform(array_slice($args, $i + 1)); } catch (\lang\Throwable $e) { Console::$err->writeLine('*** Error performing action ~ ', $e); return 1; } }
/** * Main * * @param string[] args */ public static function main(array $args) { // Read sourcecode from STDIN if no further argument is given if (0 === sizeof($args)) { $src = file_get_contents('php://stdin'); } else { $src = $args[0]; } $src = trim($src, ' ;') . ';'; // Perform $argv = array(xp::nameOf(__CLASS__)) + $args; $argc = sizeof($argv); return eval($src); }
/** * Invokes the underlying method represented by this Method object, * on the specified object with the specified parameters. * * Example: * <code> * $method= XPClass::forName('lang.Object')->getMethod('toString'); * * var_dump($method->invoke(new Object())); * </code> * * Example (passing arguments) * <code> * $method= XPClass::forName('lang.types.String')->getMethod('concat'); * * var_dump($method->invoke(new String('Hello'), array('World'))); * </code> * * Example (static invokation): * <code> * $method= XPClass::forName('util.log.Logger')->getMethod('getInstance'); * * var_dump($method->invoke(NULL)); * </code> * * @param lang.Object obj * @param var[] args default array() * @return var * @throws lang.IllegalArgumentException in case the passed object is not an instance of the declaring class * @throws lang.IllegalAccessException in case the method is not public or if it is abstract * @throws lang.reflect.TargetInvocationException for any exception raised from the invoked method */ public function invoke($obj, $args = array()) { if (NULL !== $obj && !$obj instanceof $this->_class) { throw new IllegalArgumentException(sprintf('Passed argument is not a %s class (%s)', xp::nameOf($this->_class), xp::typeOf($obj))); } // Check modifiers. If caller is an instance of this class, allow // protected method invocation (which the PHP reflection API does // not). $m = $this->_reflect->getModifiers(); if ($m & MODIFIER_ABSTRACT) { throw new IllegalAccessException(sprintf('Cannot invoke abstract %s::%s', $this->_class, $this->_reflect->getName())); } $public = $m & MODIFIER_PUBLIC; if (!$public && !$this->accessible) { $t = debug_backtrace(0); $decl = $this->_reflect->getDeclaringClass()->getName(); if ($m & MODIFIER_PROTECTED) { $allow = $t[1]['class'] === $decl || is_subclass_of($t[1]['class'], $decl); } else { $allow = $t[1]['class'] === $decl && self::$SETACCESSIBLE_AVAILABLE; } if (!$allow) { throw new IllegalAccessException(sprintf('Cannot invoke %s %s::%s from scope %s', Modifiers::stringOf($this->getModifiers()), $this->_class, $this->_reflect->getName(), $t[1]['class'])); } } // For non-public methods: Use setAccessible() / invokeArgs() combination // if possible, resort to __call() workaround. try { if ($public) { return $this->_reflect->invokeArgs($obj, (array) $args); } if (self::$SETACCESSIBLE_AVAILABLE) { $this->_reflect->setAccessible(TRUE); return $this->_reflect->invokeArgs($obj, (array) $args); } else { if ($m & MODIFIER_STATIC) { return call_user_func(array($this->_class, '__callStatic'), "" . $this->_reflect->getName(), $args); } else { return $obj->__call("" . $this->_reflect->getName(), $args); } } } catch (SystemExit $e) { throw $e; } catch (Throwable $e) { throw new TargetInvocationException($this->_class . '::' . $this->_reflect->getName(), $e); } catch (Exception $e) { throw new TargetInvocationException($this->_class . '::' . $this->_reflect->getName(), new XPException($e->getMessage())); } }
/** * Runner method * */ public static function main(array $args) { // Show command usage if invoked without arguments if (!$args) { exit(self::usage(\lang\XPClass::forName(\xp::nameOf(__CLASS__)))); } $root = new RootDoc(); for ($i = 0, $s = sizeof($args); $i < $s; $i++) { if ('-sp' === $args[$i]) { $root->setSourcePath(explode(PATH_SEPARATOR, $args[++$i])); } else { if ('-cp' === $args[$i]) { foreach (explode(PATH_SEPARATOR, $args[++$i]) as $element) { \lang\ClassLoader::registerPath($element); } } else { try { $class = \lang\XPClass::forName($args[$i]); } catch (\lang\ClassNotFoundException $e) { \util\cmd\Console::$err->writeLine('*** ', $e->getMessage()); exit(2); } if (!$class->isSubclassOf('text.doclet.Doclet')) { \util\cmd\Console::$err->writeLine('*** ', $class, ' is not a doclet'); exit(2); } $doclet = $class->newInstance(); $params = new ParamString(array_slice($args, $i)); // Show doclet usage if the command line contains "-?" (at any point). if ($params->exists('help', '?')) { self::usage($class); if ($valid = $doclet->validOptions()) { \util\cmd\Console::$err->writeLine(); \util\cmd\Console::$err->writeLine('Options:'); foreach ($valid as $name => $value) { \util\cmd\Console::$err->writeLine(' * --', $name, OPTION_ONLY == $value ? '' : '=<value>'); } } exit(3); } $root->start($doclet, $params); exit(0); } } } \util\cmd\Console::$err->writeLine('*** No doclet classname given'); exit(1); }
public static function startApplicationServer() { // Arguments to server process $args = array('debugServerProtocolToFile' => NULL); // Start server process self::$serverProcess = Runtime::getInstance()->newInstance(NULL, 'class', 'net.xp_framework.unittest.remote.TestingServer', array_values($args)); self::$serverProcess->in->close(); // Check if startup succeeded $status = self::$serverProcess->out->readLine(); if (2 != sscanf($status, '+ Service %[0-9.]:%d', self::$bindAddress[0], self::$bindAddress[1])) { try { self::shutdownApplicationServer(); } catch (IllegalStateException $e) { $status .= $e->getMessage(); } throw new PrerequisitesNotMetError('Cannot start EASC server: ' . $status, NULL); } // Add classloader with CalculatorBean client classes $a = XPClass::forName(xp::nameOf(__CLASS__))->getPackage()->getPackage('deploy')->getResourceAsStream('beans.test.CalculatorBean.xar'); self::$clientClassesLoader = ClassLoader::registerLoader(new ArchiveClassLoader(new Archive($a))); }
/** * Main * * @param string[] args */ public static function main(array $args) { $argc = sizeof($args); // Read sourcecode from STDIN if no further argument is given if (0 === $argc) { $src = file_get_contents('php://stdin'); } else { if ('--' === $args[0]) { $src = file_get_contents('php://stdin'); } else { $src = $args[0]; } } // Support <?php $src = trim($src, ' ;') . ';'; if (0 === strncmp($src, '<?php', 5)) { $src = substr($src, 6); } // Perform $argv = array(\xp::nameOf(__CLASS__)) + $args; $argc = sizeof($argv); return eval($src); }
/** * Main * * @param string[] args */ public static function main(array $args) { $way = array_shift($args); // Read sourcecode from STDIN if no further argument is given if (0 === sizeof($args)) { $src = file_get_contents('php://stdin'); } else { $src = $args[0]; } $src = trim($src, ' ;') . ';'; // Extract uses() and load classes if (0 === strncmp($src, 'uses', 4)) { $p = strpos($src, ');'); $uses = substr($src, 5, $p - 5); // "uses(" $src = substr($src, $p + 2); // ");" foreach (explode(',', $uses) as $class) { uses(trim($class, '" ')); } } // Allow missing return strstr($src, 'return ') || strstr($src, 'return;') || ($src = 'return ' . $src); // Rewrite argc, argv $argv = array(\xp::nameOf(__CLASS__)) + $args; $argc = sizeof($argv); // Perform $return = eval($src); switch ($way) { case '-w': Console::writeLine($return); break; case '-d': var_dump($return); break; } }
/** * Displays usage and exists * */ protected static function usage() { Console::$err->writeLine(self::textOf(XPClass::forName(xp::nameOf(__CLASS__))->getComment())); exit(1); }
/** * Returns qualified class name * * @param string class unqualified name * @return string */ protected function qualifiedClassName($class) { return xp::nameOf($class); }
static function stringOf($arg, $indent = '') { static $protect = array(); if (is_string($arg)) { return '"' . $arg . '"'; } else { if (is_bool($arg)) { return $arg ? 'true' : 'false'; } else { if (is_null($arg)) { return 'null'; } else { if ($arg instanceof null) { return '<null>'; } else { if (is_int($arg) || is_float($arg)) { return (string) $arg; } else { if ($arg instanceof Generic && !isset($protect[(string) $arg->hashCode()])) { $protect[(string) $arg->hashCode()] = TRUE; $s = $arg->toString(); unset($protect[(string) $arg->hashCode()]); return $indent ? str_replace("\n", "\n" . $indent, $s) : $s; } else { if (is_array($arg)) { $ser = serialize($arg); if (isset($protect[$ser])) { return '->{:recursion:}'; } $protect[$ser] = TRUE; $r = "[\n"; foreach (array_keys($arg) as $key) { $r .= $indent . ' ' . $key . ' => ' . xp::stringOf($arg[$key], $indent . ' ') . "\n"; } unset($protect[$ser]); return $r . $indent . ']'; } else { if (is_object($arg)) { $ser = serialize($arg); if (isset($protect[$ser])) { return '->{:recursion:}'; } $protect[$ser] = TRUE; $r = xp::nameOf(get_class($arg)) . " {\n"; $vars = (array) $arg; foreach (array_keys($vars) as $key) { $r .= $indent . ' ' . $key . ' => ' . xp::stringOf($vars[$key], $indent . ' ') . "\n"; } unset($protect[$ser]); return $r . $indent . '}'; } else { if (is_resource($arg)) { return 'resource(type= ' . get_resource_type($arg) . ', id= ' . (int) $arg . ')'; } } } } } } } } } }
/** * Returns the fully qualified class name for this class * (e.g. "io.File") * * @return string fully qualified class name */ public function getClassName() { return xp::nameOf(get_class($this)); }
/** * Returns values * * @param unittest.TestCase test * @param var annotation * @return var values a traversable structure */ protected function valuesFor($test, $annotation) { if (!is_array($annotation)) { // values("source") $source = $annotation; $args = array(); } else { if (isset($annotation['source'])) { // values(source= "src" [, args= ...]) $source = $annotation['source']; $args = isset($annotation['args']) ? $annotation['args'] : array(); } else { // values([1, 2, 3]) return $annotation; } } // Route "ClassName::methodName" -> static method of the given class, // "self::method" -> static method of the test class, and "method" // -> the run test's instance method if (FALSE === ($p = strpos($source, '::'))) { return $test->getClass()->getMethod($source)->setAccessible(TRUE)->invoke($test, $args); } $ref = substr($source, 0, $p); if ('self' === $ref) { $class = $test->getClass(); } else { if (strstr($ref, '.')) { $class = XPClass::forName($ref); } else { $class = XPClass::forName(xp::nameOf($ref)); } } return $class->getMethod(substr($source, $p + 2))->invoke(NULL, $args); }
static function __static() { \lang\ClassLoader::registerLoader(new \lang\archive\ArchiveClassLoader(new Archive(\lang\XPClass::forName(\xp::nameOf(__CLASS__))->getPackage()->getPackage('lib')->getResourceAsStream('fqcns.xar')))); \lang\XPClass::forName('info.binford6100.Date'); \lang\XPClass::forName('de.thekid.util.ObjectComparator'); }
/** * Setup this test. Registeres class loaders deleates for the * afforementioned XARs * */ public function setUp() { $this->libraryLoader = \lang\ClassLoader::registerLoader(new \lang\archive\ArchiveClassLoader(new Archive(\lang\XPClass::forName(\xp::nameOf(__CLASS__))->getPackage()->getPackage('lib')->getResourceAsStream('three-and-four.xar')))); $this->brokenLoader = \lang\ClassLoader::registerLoader(new \lang\archive\ArchiveClassLoader(new Archive(\lang\XPClass::forName(\xp::nameOf(__CLASS__))->getPackage()->getPackage('lib')->getResourceAsStream('broken.xar')))); $this->containedLoader = \lang\ClassLoader::registerLoader(new \lang\archive\ArchiveClassLoader(new Archive($this->libraryLoader->getResourceAsStream('contained.xar')))); }
/** * Main * * @param string[] args */ public static function main(array $args) { Console::$err->writeLine(XPClass::forName(xp::nameOf(__CLASS__))->getPackage()->getResource($args[0])); exit((int) $args[1]); }
public static function registerClientClasses() { $a = \lang\XPClass::forName(\xp::nameOf(__CLASS__))->getPackage()->getPackage('deploy')->getResourceAsStream('beans.test.CalculatorBean.xar'); self::$clientClassesLoader = \lang\ClassLoader::registerLoader(new \lang\archive\ArchiveClassLoader(new Archive($a))); }
/** * Setup this test. Registeres class loaders deleates for the * afforementioned XARs * */ public function setUp() { $this->libraryLoader = ClassLoader::registerLoader(new ArchiveClassLoader(new Archive(XPClass::forName(xp::nameOf(__CLASS__))->getPackage()->getPackage('lib')->getResourceAsStream('three-and-four.xar')))); }
/** * Gets the currency instance for a given currency code * * @param string code ISO 4217 code * @return util.Currency * @throws lang.IllegalArgumentException */ public static function getInstance($code) { return Enum::valueOf(XPClass::forName(xp::nameOf(__CLASS__)), $code); }
/** * Displays usage and exists * * @return int */ protected static function usage() { Console::$err->writeLine(self::textOf(\lang\XPClass::forName(\xp::nameOf(__CLASS__))->getComment())); return 1; }
/** * Helper method to turn a given value into a class object * * @param var class * @return lang.XPClass */ protected static function classOf($class) { if ($class instanceof XPClass) { return $class; } else { return XPClass::forName(strstr($class, '.') ? $class : xp::nameOf($class)); } }
/** * Returns an on-the-wire representation of the given value * * @param server.protocol.Serializer serializer * @param lang.Object value * @param [:var] context default array() * @return string */ public function representationOf($serializer, $value, $context = array()) { return 't:4:{' . 's:4:"file";' . $serializer->representationOf(NULL == $value->file ? NULL : basename($value->file)) . 's:5:"class";' . $serializer->representationOf(NULL == $value->class ? NULL : xp::nameOf($value->class)) . 's:6:"method";' . $serializer->representationOf($value->method) . 's:4:"line";' . $serializer->representationOf($value->line) . '}'; }
/** * Qualifies a class name by looking at known or used classes. * * @param text.doclet.Doc doc * @param string name * @return string qualified name */ public function qualifyName($doc, $name) { if (isset(xp::$cn[$name])) { foreach ($doc->usedClasses->classes as $class) { if (xp::reflect($class) === $name) { return $class; } } $lookup = xp::$cn[$name]; } else { $lookup = NULL; } // Nothing found! if (!$lookup && !($lookup = xp::nameOf($name))) { throw new IllegalStateException(sprintf('Could not find class %s in %s', xp::stringOf($name), xp::stringOf($this->sourcepath))); } return $lookup; }
/** * Retrieve return type * * @return string */ public function getReturnTypeName() { return xp::nameOf($this->_class); }
/** * Retrieve details for a specified class and field. Note: Results * from this method are cached! * * @param string class unqualified class name * @param string method * @return array or NULL if not available */ public static function detailsForField($class, $field) { $details = self::detailsForClass(xp::nameOf($class)); return $details ? isset($details[0][$field]) ? $details[0][$field] : NULL : NULL; }
/** * Entry point method * * @param string[] args */ public static function main(array $args) { \util\cmd\Console::$err->writeLine(\lang\XPClass::forName(\xp::nameOf(__CLASS__))->getPackage()->getResource($args[0])); return 0xff; }
/** * Displays usage * * @return int exitcode */ protected function usage() { $this->err->writeLine($this->textOf(XPClass::forName(xp::nameOf(__CLASS__))->getComment())); return 1; }
/** * Main method * * @param util.cmd.ParamString params * @return int */ public function run(ParamString $params) { // No arguments given - show our own usage if ($params->count < 1) { self::$err->writeLine(self::textOf(XPClass::forName(xp::nameOf(__CLASS__))->getComment())); return 1; } // Configure properties $pm = PropertyManager::getInstance(); // Separate runner options from class options for ($offset = 0, $i = 0; $i < $params->count; $i++) { switch ($params->list[$i]) { case '-c': if (0 == strncmp('res://', $params->list[$i + 1], 6)) { $pm->appendSource(new ResourcePropertySource(substr($params->list[$i + 1], 6))); } else { $pm->appendSource(new FilesystemPropertySource($params->list[$i + 1])); } $offset += 2; $i++; break; case '-cp': ClassLoader::registerPath($params->list[$i + 1], NULL); $offset += 2; $i++; break; case '-v': $this->verbose = TRUE; $offset += 1; $i++; break; default: break 2; } } // Sanity check if (!$params->exists($offset)) { self::$err->writeLine('*** Missing classname'); return 1; } // Use default path for PropertyManager if no sources set if (!$pm->getSources()) { $pm->configure(self::DEFAULT_CONFIG_PATH); } unset($params->list[-1]); $classname = $params->value($offset); $classparams = new ParamString(array_slice($params->list, $offset + 1)); // Class file or class name if (strstr($classname, xp::CLASS_FILE_EXT)) { $file = new File($classname); if (!$file->exists()) { self::$err->writeLine('*** Cannot load class from non-existant file ', $classname); return 1; } $uri = $file->getURI(); $path = dirname($uri); $paths = array_flip(array_map('realpath', xp::$classpath)); $class = NULL; while (FALSE !== ($pos = strrpos($path, DIRECTORY_SEPARATOR))) { if (isset($paths[$path])) { $class = XPClass::forName(strtr(substr($uri, strlen($path) + 1, -10), DIRECTORY_SEPARATOR, '.')); break; } $path = substr($path, 0, $pos); } if (!$class) { self::$err->writeLine('*** Cannot load class from ', $file); return 1; } } else { try { $class = XPClass::forName($classname); } catch (ClassNotFoundException $e) { self::$err->writeLine('*** ', $this->verbose ? $e : $e->getMessage()); return 1; } } // Check whether class is runnable if (!$class->isSubclassOf('lang.Runnable')) { self::$err->writeLine('*** ', $class->getName(), ' is not runnable'); return 1; } // Usage if ($classparams->exists('help', '?')) { self::showUsage($class); return 0; } // Load, instantiate and initialize $l = Logger::getInstance(); $pm->hasProperties('log') && $l->configure($pm->getProperties('log')); $cm = ConnectionManager::getInstance(); $pm->hasProperties('database') && $cm->configure($pm->getProperties('database')); // Setup logger context for all registered log categories foreach (Logger::getInstance()->getCategories() as $category) { if (NULL === ($context = $category->getContext()) || !$context instanceof EnvironmentAware) { continue; } $context->setHostname(System::getProperty('host.name')); $context->setRunner($this->getClassName()); $context->setInstance($class->getName()); $context->setResource(NULL); $context->setParams($params->string); } $instance = $class->newInstance(); $instance->in = self::$in; $instance->out = self::$out; $instance->err = self::$err; $methods = $class->getMethods(); // Injection foreach ($methods as $method) { if (!$method->hasAnnotation('inject')) { continue; } $inject = $method->getAnnotation('inject'); if (isset($inject['type'])) { $type = $inject['type']; } else { if ($restriction = $method->getParameter(0)->getTypeRestriction()) { $type = $restriction->getName(); } else { $type = $method->getParameter(0)->getType()->getName(); } } try { switch ($type) { case 'rdbms.DBConnection': $args = array($cm->getByHost($inject['name'], 0)); break; case 'util.Properties': $p = $pm->getProperties($inject['name']); // If a PropertyAccess is retrieved which is not a util.Properties, // then, for BC sake, convert it into a util.Properties if ($p instanceof PropertyAccess && !$p instanceof Properties) { $convert = Properties::fromString(''); $section = $p->getFirstSection(); while ($section) { // HACK: Properties::writeSection() would first attempts to // read the whole file, we cannot make use of it. $convert->_data[$section] = $p->readSection($section); $section = $p->getNextSection(); } $args = array($convert); } else { $args = array($p); } break; case 'util.log.LogCategory': $args = array($l->getCategory($inject['name'])); break; default: self::$err->writeLine('*** Unknown injection type "' . $type . '" at method "' . $method->getName() . '"'); return 2; } $method->invoke($instance, $args); } catch (TargetInvocationException $e) { self::$err->writeLine('*** Error injecting ' . $type . ' ' . $inject['name'] . ': ' . $e->getCause()->compoundMessage()); return 2; } catch (Throwable $e) { self::$err->writeLine('*** Error injecting ' . $type . ' ' . $inject['name'] . ': ' . $e->compoundMessage()); return 2; } } // Arguments foreach ($methods as $method) { if ($method->hasAnnotation('args')) { // Pass all arguments if (!$method->hasAnnotation('args', 'select')) { $begin = 0; $end = $classparams->count; $pass = array_slice($classparams->list, 0, $end); } else { $pass = array(); foreach (preg_split('/, ?/', $method->getAnnotation('args', 'select')) as $def) { if (is_numeric($def) || '-' == $def[0]) { $pass[] = $classparams->value((int) $def); } else { sscanf($def, '[%d..%d]', $begin, $end); isset($begin) || ($begin = 0); isset($end) || ($end = $classparams->count - 1); while ($begin <= $end) { $pass[] = $classparams->value($begin++); } } } } try { $method->invoke($instance, array($pass)); } catch (Throwable $e) { self::$err->writeLine('*** Error for arguments ' . $begin . '..' . $end . ': ', $this->verbose ? $e : $e->getMessage()); return 2; } } else { if ($method->hasAnnotation('arg')) { // Pass arguments $arg = $method->getAnnotation('arg'); if (isset($arg['position'])) { $name = '#' . ($arg['position'] + 1); $select = intval($arg['position']); $short = NULL; } else { if (isset($arg['name'])) { $name = $select = $arg['name']; $short = isset($arg['short']) ? $arg['short'] : NULL; } else { $name = $select = strtolower(preg_replace('/^set/', '', $method->getName())); $short = isset($arg['short']) ? $arg['short'] : NULL; } } if (0 == $method->numParameters()) { if (!$classparams->exists($select, $short)) { continue; } $args = array(); } else { if (!$classparams->exists($select, $short)) { list($first, ) = $method->getParameters(); if (!$first->isOptional()) { self::$err->writeLine('*** Argument ' . $name . ' does not exist!'); return 2; } $args = array(); } else { $args = array($classparams->value($select, $short)); } } try { $method->invoke($instance, $args); } catch (TargetInvocationException $e) { self::$err->writeLine('*** Error for argument ' . $name . ': ', $this->verbose ? $e->getCause() : $e->getCause()->compoundMessage()); return 2; } } } } try { $instance->run(); } catch (Throwable $t) { self::$err->writeLine('*** ', $t->toString()); return 70; // EX_SOFTWARE according to sysexits.h } return 0; }
/** * Changes the value of the field represented by this Field, on the * specified object. * * @param lang.Object instance * @param var value * @throws lang.IllegalArgumentException in case the passed object is not an instance of the declaring class * @throws lang.IllegalAccessException in case this field is not public */ public function set($instance, $value) { if (NULL !== $instance && !$instance instanceof $this->_class) { throw new IllegalArgumentException(sprintf('Passed argument is not a %s class (%s)', xp::nameOf($this->_class), xp::typeOf($instance))); } // Check modifiers. If caller is an instance of this class, allow // protected method invocation (which the PHP reflection API does // not). $m = $this->_reflect->getModifiers(); $public = $m & MODIFIER_PUBLIC; if (!$public && !$this->accessible) { $t = debug_backtrace(0); $decl = $this->_reflect->getDeclaringClass()->getName(); if ($m & MODIFIER_PROTECTED) { $allow = $t[1]['class'] === $decl || is_subclass_of($t[1]['class'], $decl); } else { $allow = $t[1]['class'] === $decl; } if (!$allow) { throw new IllegalAccessException(sprintf('Cannot write %s %s::$%s from scope %s', Modifiers::stringOf($this->getModifiers()), xp::nameOf($this->_class), $this->_reflect->getName(), $t[1]['class'])); } } try { $public || $this->_reflect->setAccessible(TRUE); $this->_reflect->setValue($instance, $value); } catch (Throwable $e) { throw $e; } catch (Exception $e) { throw new XPException($e->getMessage()); } }