/** * Helper method * * @param string name * @param lang.XPClass class * @throws unittest.AssertionFailedError */ protected function defineInterface($name, $parents, $bytes) { if (interface_exists(xp::reflect($name), FALSE)) { $this->fail('Interface "' . $name . '" may not exist!'); } return ClassLoader::defineInterface($name, $parents, $bytes); }
/** * Read a record * * @param string[] fields if omitted, class fields are used in order of appearance * @return lang.Object or NULL if end of the file is reached */ public function read(array $fields = array()) { if (NULL === ($values = $this->readValues())) { return NULL; } if (!$fields) { foreach ($this->class->getFields() as $f) { $fields[] = $f->getName(); } } // Create an object by deserialization. This enables us to also set // private and protected fields as well as avoids the constructor call. $n = xp::reflect($this->class->getName()); $s = 'O:' . strlen($n) . ':"' . $n . '":' . sizeof($fields) . ':{'; foreach ($fields as $i => $name) { $f = $this->class->getField($name); switch ($f->getModifiers() & (MODIFIER_PUBLIC | MODIFIER_PROTECTED | MODIFIER_PRIVATE)) { case MODIFIER_PUBLIC: $s .= serialize($f->getName()); break; case MODIFIER_PROTECTED: $s .= serialize("*" . $f->getName()); break; case MODIFIER_PRIVATE: $s .= serialize("" . $n . "" . $f->getName()); break; } $s .= serialize($values[$i]); } $s .= '}'; return unserialize($s); }
static function __static() { libxml_use_internal_errors(TRUE); // Forwards compatibility hack: In XSL, we use XSLCallback::invoke(), but // the class in namespaced PHP is called xml::XSLCallback. Ensure a class // called "XSLCallback" (without namespaces) exists instead of requiring // everybody to change their XSL files! class_exists('XSLCallback', FALSE) || eval('class XSLCallback extends ' . xp::reflect('xml.XSLCallback') . ' {}'); }
function runnable() { $p = new ParamString(); $class = xp::reflect(basename($p->value(0), '.class.php')); $target = array($class, 'main'); if (!is_callable($target)) { xp::error('Target ' . $class . '::main() is not runnable'); // Bails out } xp::$cn[$class] = 'Runnable$' . $class; exit(call_user_func($target, $p)); }
/** * 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; }
/** * Load the class by the specified name * * @param string class fully qualified class name io.File * @return string class name * @throws lang.ClassNotFoundException in case the class can not be found * @throws lang.ClassFormatException in case the class format is invalud */ public function loadClass0($class) { if (isset(xp::$cl[$class])) { return xp::reflect($class); } // Load class $package = NULL; xp::$cl[$class] = $this->getClassName() . '://' . $this->path; xp::$cll++; try { $r = (include $this->classUri($class)); } catch (ClassLoadingException $e) { xp::$cll--; $decl = NULL; if (NULL === $package) { $decl = substr($class, FALSE === ($p = strrpos($class, '.')) ? 0 : $p + 1); } else { $decl = strtr($class, '.', '·'); } // If class was declared, but loading threw an exception it means // a "soft" dependency, one that is only required at runtime, was // not loaded, the class itself has been declared. if (class_exists($decl, FALSE) || interface_exists($decl, FALSE)) { raise('lang.ClassDependencyException', $class, array($this), $e); } // If otherwise, a "hard" dependency could not be loaded, eg. the // base class or a required interface and thus the class could not // be declared. raise('lang.ClassLinkageException', $class, array($this), $e); } xp::$cll--; if (FALSE === $r) { unset(xp::$cl[$class]); throw new ClassNotFoundException($class, array($this)); } // Register it if (NULL === $package) { if (FALSE === ($p = strrpos($class, '.'))) { $name = $class; } else { $name = substr($class, $p + 1); if (!class_exists($name, FALSE) && !interface_exists($name, FALSE)) { $name = strtr($class, '.', '\\'); if (!class_exists($name, FALSE) && !interface_exists($name, FALSE)) { unset(xp::$cl[$class]); raise('lang.ClassFormatException', 'Class "' . $name . '" not declared in loaded file'); } } else { class_alias($name, strtr($class, '.', '\\')); } } } else { $name = strtr($class, '.', '·'); class_alias($name, strtr($class, '.', '\\')); } xp::$cn[$name] = $class; method_exists($name, '__static') && (xp::$cli[] = array($name, '__static')); if (0 === xp::$cll) { $invocations = xp::$cli; xp::$cli = array(); foreach ($invocations as $inv) { call_user_func($inv); } } return $name; }
/** * Constructor * * @param string rootName default 'document' */ public function __construct($rootName = 'document') { parent::__construct($rootName); $this->nodeType = xp::reflect('xml.soap.xp.XPSoapNode'); }
/** * Constructor * * @param string rootName default 'document' */ public function __construct($rootName = 'document') { $this->root = new Node($rootName); $this->nodeType = xp::reflect('xml.Node'); }
public function sorting() { $list = array(new \util\Date('1977-12-14'), new \util\Date('2002-02-21'), new \util\Date('1980-05-28')); usort($list, array(\xp::reflect('util.DateUtil'), 'compare')); $this->assertEquals(new \util\Date('1977-12-14'), $list[0], 'offset 0') && $this->assertEquals(new \util\Date('1980-05-28'), $list[1], 'offset 1') && $this->assertEquals(new \util\Date('2002-02-21'), $list[2], 'offset 2'); }
public function reflectedNameOfClass() { $class = $this->fixture->getClass(); $this->assertEquals('net·xp_framework·unittest·core·generics·Lookup··String¸TestCase', xp::reflect($class->getName())); }
static function reflect($type) { if ('string' === $type || 'int' === $type || 'double' === $type || 'bool' == $type) { return '■' . $type; } else { if ('var' === $type) { return $type; } else { if ('[]' === substr($type, -2)) { return 'д' . xp::reflect(substr($type, 0, -2)); } else { if ('[:' === substr($type, 0, 2)) { return '╗' . xp::reflect(substr($type, 2, -1)); } else { if (FALSE !== ($p = strpos($type, '<'))) { $l = xp::reflect(substr($type, 0, $p)) . 'ии'; for ($args = substr($type, $p + 1, -1) . ',', $o = 0, $brackets = 0, $i = 0, $s = strlen($args); $i < $s; $i++) { if (',' === $args[$i] && 0 === $brackets) { $l .= xp::reflect(ltrim(substr($args, $o, $i - $o))) . 'И'; $o = $i + 1; } else { if ('<' === $args[$i]) { $brackets++; } else { if ('>' === $args[$i]) { $brackets--; } } } } return substr($l, 0, -1); } else { $l = array_search($type, xp::$cn, TRUE); return $l ?: substr($type, FALSE === ($p = strrpos($type, '.')) ? 0 : $p + 1); } } } } } }
/** * Generates the class header. * "class <name> extends <baseClass> implements IProxy, <interfaces> {" * * @param lang.XPClass baseClass * @param lang.XPClass[] interfaces * @return string */ private function generateHead($baseClass, $interfaces) { // Create proxy class' name, using a unique identifier and a prefix $name = $this->getProxyName(); $bytes = 'class ' . $name . ' extends ' . xp::reflect($baseClass->getName()) . ' implements IMockProxy, '; for ($j = 0; $j < sizeof($interfaces); $j++) { $bytes .= xp::reflect($interfaces[$j]->getName()) . ', '; } $bytes = substr($bytes, 0, -2) . " {\n"; return $bytes; }
/** * Load the class by the specified name * * @param string class fully qualified class name io.File * @return string class name * @throws lang.ClassNotFoundException in case the class can not be found * @throws lang.ClassFormatException in case the class format is invalud */ public function loadClass0($class) { if (isset(xp::$cl[$class])) { return xp::reflect($class); } // Load class $package = NULL; xp::$cl[$class] = $this->getClassName() . '://' . $this->path; xp::$cll++; try { $r = (include $this->classUri($class)); } catch (ClassLoadingException $e) { xp::$cll--; $decl = NULL; if (NULL === $package) { $decl = substr($class, FALSE === ($p = strrpos($class, '.')) ? 0 : $p + 1); } else { $decl = strtr($class, '.', '·'); } // If class was declared, but loading threw an exception it means // a "soft" dependency, one that is only required at runtime, was // not loaded, the class itself has been declared. if (class_exists($decl, FALSE) || interface_exists($decl, FALSE)) { raise('lang.ClassDependencyException', $class, array($this), $e); } // If otherwise, a "hard" dependency could not be loaded, eg. the // base class or a required interface and thus the class could not // be declared. raise('lang.ClassLinkageException', $class, array($this), $e); } xp::$cll--; if (FALSE === $r) { unset(xp::$cl[$class]); $e = new ClassNotFoundException($class, array($this)); xp::gc(__FILE__); throw $e; } // Register class name / literal mapping, which is one of the following: // // * No dot in the qualified class name -> ClassName // * Dotted version declares $package -> com·example·ClassName // * Dotted version resolves to a namespaced class -> com\example\ClassName // * Dotted version resolves to class in the global namespace -> ClassName // // Create aliases for dotted versions not resolving to namespaces if (FALSE === ($p = strrpos($class, '.'))) { $name = $class; } else { if (NULL !== $package) { $name = strtr($class, '.', '·'); class_alias($name, strtr($class, '.', '\\')); } else { if (($ns = strtr($class, '.', '\\')) && (class_exists($ns, FALSE) || interface_exists($ns, FALSE))) { $name = $ns; } else { if (($cl = substr($class, $p + 1)) && (class_exists($cl, FALSE) || interface_exists($cl, FALSE))) { $name = $cl; class_alias($name, strtr($class, '.', '\\')); } else { unset(xp::$cl[$class]); raise('lang.ClassFormatException', 'Class "' . $class . '" not declared in loaded file'); } } } } xp::$cn[$name] = $class; method_exists($name, '__static') && (xp::$cli[] = array($name, '__static')); if (0 === xp::$cll) { $invocations = xp::$cli; xp::$cli = array(); foreach ($invocations as $inv) { call_user_func($inv); } } return $name; }
/** * Generates code for a method. * * @param lang.reflect.Method method * @return string */ private function generateMethod($method) { $bytes = ''; // Build signature and argument list if ($method->hasAnnotation('overloaded')) { $signatures = $method->getAnnotation('overloaded', 'signatures'); $methodax = 0; $cases = array(); foreach ($signatures as $signature) { $args = sizeof($signature); $methodax = max($methodax, $args - 1); if (isset($cases[$args])) { continue; } $cases[$args] = 'case ' . $args . ': ' . 'return $this->' . $this->getHandlerName() . '->invoke($this, \'' . $method->getName(TRUE) . '\', array(' . ($args ? '$_' . implode(', $_', range(0, $args - 1)) : '') . '));'; } // Create method $bytes .= 'public function ' . $method->getName() . '($_' . implode('= NULL, $_', range(0, $methodax)) . '= NULL) { ' . 'switch (func_num_args()) {' . implode("\n", $cases) . ' default: throw new IllegalArgumentException(\'Illegal number of arguments\'); }' . '}' . "\n"; } else { $signature = $args = ''; foreach ($method->getParameters() as $param) { $restriction = $param->getTypeRestriction(); $signature .= ', ' . ($restriction ? xp::reflect($restriction->getName()) : '') . ' $' . $param->getName(); $args .= ', $' . $param->getName(); $param->isOptional() && ($signature .= '= ' . var_export($param->getDefaultValue(), TRUE)); } $signature = substr($signature, 2); $args = substr($args, 2); // Create method $bytes .= 'public function ' . $method->getName() . '(' . $signature . ') { ' . 'return $this->' . $this->getHandlerName() . '->invoke($this, \'' . $method->getName(TRUE) . '\', func_get_args()); ' . '}' . "\n"; } return $bytes; }
/** * Returns a list of subpackages in this package. * * @return lang.reflect.Package[] */ public function getPackages() { return array_map(array(xp::reflect('lang.reflect.Package'), 'forName'), $this->getPackageNames()); }
/** * Registers a class map * * @param xml.QName object * @param lang.XPClass class */ public function registerMapping(QName $qname, XPClass $class) { $this->map[$qname->localpart] = xp::reflect($class->getName()); }
/** * Returns type literal * * @return string */ public function literal() { return xp::reflect($this->name); }
/** * Loads a class * * @param string class fully qualified class name * @return string class name of class loaded * @throws lang.ClassNotFoundException in case the class can not be found * @throws lang.ClassFormatException in case the class format is invalud */ public function loadClass0($class) { if (isset(xp::$cl[$class])) { return xp::reflect($class); } // Ask delegates foreach (self::$delegates as $delegate) { if ($delegate->providesClass($class)) { return $delegate->loadClass0($class); } } throw new ClassNotFoundException($class, self::getLoaders()); }
public function reflect_this() { $this->assertEquals(__CLASS__, xp::reflect($this->getClassName())); }
/** * Retrieve exception types * * @return lang.XPClass[] */ public function getExceptionTypes() { $details = XPClass::detailsForMethod($this->_reflect->getDeclaringClass()->getName(), $this->_reflect->getName()); return $details ? array_map(array(xp::reflect('lang.XPClass'), 'forName'), $details[DETAIL_THROWS]) : array(); }
/** * Returns the XPClass object for a proxy class given a class loader * and an array of interfaces. The proxy class will be defined by the * specified class loader and will implement all of the supplied * interfaces (also loaded by the classloader). * * @param lang.IClassLoader classloader * @param lang.XPClass[] interfaces names of the interfaces to implement * @return lang.XPClass * @throws lang.IllegalArgumentException */ public static function getProxyClass(IClassLoader $classloader, array $interfaces) { static $num = 0; static $cache = array(); $t = sizeof($interfaces); if (0 === $t) { throw new IllegalArgumentException('Interfaces may not be empty'); } // Calculate cache key (composed of the names of all interfaces) $key = $classloader->hashCode() . ':' . implode(';', array_map(create_function('$i', 'return $i->getName();'), $interfaces)); if (isset($cache[$key])) { return $cache[$key]; } // Create proxy class' name, using a unique identifier and a prefix $name = self::PREFIX . $num++; $bytes = 'class ' . $name . ' extends ' . xp::reflect('lang.reflect.Proxy') . ' implements '; $added = array(); for ($j = 0; $j < $t; $j++) { $bytes .= xp::reflect($interfaces[$j]->getName()) . ', '; } $bytes = substr($bytes, 0, -2) . " {\n"; for ($j = 0; $j < $t; $j++) { $if = $interfaces[$j]; // Verify that the Class object actually represents an interface if (!$if->isInterface()) { throw new IllegalArgumentException($if->getName() . ' is not an interface'); } // Implement all the interface's methods foreach ($if->getMethods() as $m) { // Check for already declared methods, do not redeclare them if (isset($added[$m->getName()])) { continue; } $added[$m->getName()] = TRUE; // Build signature and argument list if ($m->hasAnnotation('overloaded')) { $signatures = $m->getAnnotation('overloaded', 'signatures'); $max = 0; $cases = array(); foreach ($signatures as $signature) { $args = sizeof($signature); $max = max($max, $args - 1); if (isset($cases[$args])) { continue; } $cases[$args] = 'case ' . $args . ': ' . 'return $this->_h->invoke($this, \'' . $m->getName(TRUE) . '\', array(' . ($args ? '$_' . implode(', $_', range(0, $args - 1)) : '') . '));'; } // Create method $bytes .= 'function ' . $m->getName() . '($_' . implode('= NULL, $_', range(0, $max)) . '= NULL) { ' . 'switch (func_num_args()) {' . implode("\n", $cases) . ' default: throw new IllegalArgumentException(\'Illegal number of arguments\'); }' . '}' . "\n"; } else { $signature = $args = ''; foreach ($m->getParameters() as $param) { $signature .= ', '; $restriction = $param->getTypeRestriction(); if ($restriction instanceof XPClass) { $signature .= '\\' . strtr($restriction->getName(), array('php.' => '', '.' => '\\')); } else { if (Primitive::$ARRAY->equals($restriction)) { $signature .= 'array'; } } $signature .= ' $' . $param->getName(); $args .= ', $' . $param->getName(); $param->isOptional() && ($signature .= '= ' . var_export($param->getDefaultValue(), TRUE)); } $signature = substr($signature, 2); $args = substr($args, 2); // Create method $bytes .= 'function ' . $m->getName() . '(' . $signature . ') { ' . 'return $this->_h->invoke($this, \'' . $m->getName(TRUE) . '\', array(' . $args . ')); ' . '}' . "\n"; } } } $bytes .= ' }'; // Define the generated class try { $dyn = DynamicClassLoader::instanceFor(__METHOD__); $dyn->setClassBytes($name, $bytes); $class = $dyn->loadClass($name); } catch (FormatException $e) { throw new IllegalArgumentException($e->getMessage()); } // Update cache and return XPClass object $cache[$key] = $class; return $class; }
/** * Retrieve an instance by a given XP class name * * @param string fully qualified class name * @return rdbms.Peer */ public static function forName($classname) { return self::getInstance(xp::reflect($classname)); }
public function initializerCalled() { $name = 'net.xp_framework.unittest.reflection.LoaderTestClass'; if (class_exists(\xp::reflect($name), false)) { return $this->fail('Class "' . $name . '" may not exist!'); } $this->assertXPClass($name, \lang\ClassLoader::getDefault()->loadClass($name)); $this->assertTrue(LoaderTestClass::initializerCalled()); }
public function reflectedNameOfClass() { $class = $this->fixture->getClass(); $this->assertEquals('net\\xp_framework\\unittest\\core\\generics\\Lookup··String¸TestCase', \xp::reflect($class->getName())); }