コード例 #1
0
 /**
  * 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);
 }
コード例 #2
0
 /**
  * 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);
 }
コード例 #3
0
 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') . ' {}');
 }
コード例 #4
0
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));
}
コード例 #5
0
 /**
  * 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;
 }
コード例 #6
0
 /**
  * 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;
 }
コード例 #7
0
 /**
  * Constructor
  *
  * @param   string rootName default 'document'
  */
 public function __construct($rootName = 'document')
 {
     parent::__construct($rootName);
     $this->nodeType = xp::reflect('xml.soap.xp.XPSoapNode');
 }
コード例 #8
0
 /**
  * Constructor
  *
  * @param   string rootName default 'document'
  */
 public function __construct($rootName = 'document')
 {
     $this->root = new Node($rootName);
     $this->nodeType = xp::reflect('xml.Node');
 }
コード例 #9
0
 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');
 }
コード例 #10
0
 public function reflectedNameOfClass()
 {
     $class = $this->fixture->getClass();
     $this->assertEquals('net·xp_framework·unittest·core·generics·Lookup··String¸TestCase', xp::reflect($class->getName()));
 }
コード例 #11
0
ファイル: lang.base.php プロジェクト: Gamepay/xp-framework
 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);
                     }
                 }
             }
         }
     }
 }
コード例 #12
0
 /**
  * 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;
 }
コード例 #13
0
 /**
  * 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;
 }
コード例 #14
0
 /**
  * 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;
 }
コード例 #15
0
 /**
  * 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());
 }
コード例 #16
0
 /**
  * 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());
 }
コード例 #17
0
 /**
  * Returns type literal
  *
  * @return  string
  */
 public function literal()
 {
     return xp::reflect($this->name);
 }
コード例 #18
0
 /**
  * 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());
 }
コード例 #19
0
ファイル: XpTest.class.php プロジェクト: Gamepay/xp-framework
 public function reflect_this()
 {
     $this->assertEquals(__CLASS__, xp::reflect($this->getClassName()));
 }
コード例 #20
0
 /**
  * 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();
 }
コード例 #21
0
 /**
  * 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;
 }
コード例 #22
0
 /**
  * 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));
 }
コード例 #23
0
 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());
 }
コード例 #24
0
 public function reflectedNameOfClass()
 {
     $class = $this->fixture->getClass();
     $this->assertEquals('net\\xp_framework\\unittest\\core\\generics\\Lookup··String¸TestCase', \xp::reflect($class->getName()));
 }