/** * Create a new verification * * @param (function(): var)|string $callable */ public function __construct($callable) { if ($callable instanceof \Closure) { $this->verify = $callable; $this->prerequisite = '<function()>'; } else { if (0 === strncmp($callable, 'self::', 6)) { $method = substr($callable, 6); $this->verify = function () use($method) { return call_user_func(['self', $method]); }; $this->prerequisite = $callable; } else { if (false !== ($p = strpos($callable, '::'))) { $class = literal(substr($callable, 0, $p)); $method = substr($callable, $p + 2); $this->verify = function () use($class, $method) { return call_user_func([$class, $method]); }; $this->prerequisite = $callable; } else { $this->verify = function () use($callable) { return call_user_func([$this, $callable]); }; $this->prerequisite = '$this->' . $callable; } } } }
public function getForm($action) { $form = new form_renderer($action); $form->append($tabs = new widget_tabs()); foreach ($this->info as $cat => $category) { $inputs = array(); foreach ($category['items'] as $id => $field) { $name = "options[{$cat}][{$id}]"; $value = $this->{$cat}->{$id}; $class = 'data_option_' . $field['type']; if (class_exists($class)) { $provider = new $class($field); $inputs[] = $provider->getField($name, $value); } elseif ($field['type'] == 'text') { $inputs[] = new form_field_text($name, $field['caption'], $value); } elseif ($field['type'] == 'textarea') { $inputs[] = new form_field_textarea($name, $field['caption'], $value); } elseif ($field['type'] == 'checkbox') { $inputs[] = new form_field_checkbox($name, $field['caption'], $value); } } $tabs->add(literal($category['caption']), implode('', $inputs)); } return $form; }
/** * Wraps around a function which defines types, giving it unique names and * verifying the type has not been defined before. * * @param string $annotations * @param string $name Uses a unique name if NULL is passed * @param var $define A function * @return lang.XPClass * @throws unittest.AssertionFailedError */ protected function defineType($annotations, $name, $define) { $t = $name ?: nameof($this) . '__' . $this->name; $spec = trim($annotations . ' ' . $t); if (interface_exists(literal($t), false) || class_exists(literal($t), false)) { $this->fail('Type may not exist!', $t, null); } return $define($spec); }
/** * Resolve this value * * @param lang.mirrors.Source $source * @return var */ public function resolve($type) { $resolved = $type->resolve($this->type); if ('class' === $this->name) { return literal($resolved->typeName()); } else { if ('$' === $this->name[0]) { $field = $resolved->fieldNamed(substr($this->name, 1)); return $field['read'](null); } else { return $resolved->constantNamed($this->name); } } }
public function __construct($user, $sysadmin) { $rights = db()->query("SELECT g.rights FROM user_group_owner go\n\t\t\tJOIN user_groups g on go.`group` = g.id WHERE go.user = %d\n\t\t\tAND go.start_date < %d\n\t\t\tAND ( go.end_date IS NULL OR go.end_date > %d)", $user, time(), time()); foreach ($rights as $r) { if ($r = unserialize($r['rights'])) { $this->rights = array_merge_recursive($this->rights, $r); } } foreach (iv::get('rights') as $type => $provider) { $class = literal($provider['provider']); $this->providers[$type] = new $class($provider['arguments'], $provider['always']); $this->providers[$type]->name = literal($provider['caption']); } $this->sysadmin = $sysadmin; }
/** * 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 (literal($class) === $name) { return $class; } } $lookup = \xp::$cn[$name]; } else { $lookup = null; } // Nothing found! if (!$lookup) { throw new \lang\IllegalStateException(sprintf('Could not find class %s in %s', \xp::stringOf($name), \xp::stringOf($this->sourcepath))); } return $lookup; }
/** * 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(literal($classname)); }
/** * Compiles a class if necessary * * @param string $class * @return string * @throws lang.ClassLoadingException */ public function loadClass0($class) { if (isset(\xp::$cl[$class])) { return literal($class); } // Locate sourcecode if (null === ($source = $this->locateSource($class))) { throw new ClassNotFoundException($class); } if (null === $this->emitter) { $this->emitter = Emitter::newInstance(); } // Parse, then emit source $this->debug && fputs(STDERR, "COMPILE " . $source->toString() . "\n"); $scope = new TaskScope(new CompilationTask($source, new NullDiagnosticListener(), $this->files, $this->emitter)); $this->emitter->clearMessages(); try { $r = $this->emitter->emit($source->getSyntax()->parse($source->getInputStream()), $scope); } catch (ParseException $e) { $this->debug && $e->printStackTrace(); throw new ClassFormatException('Cannot compile ' . $source->getURI() . ': ' . $e->formattedErrors(''), $e); } catch (FormatException $e) { $this->debug && $e->printStackTrace(); throw new JitCompilationError($class, [$this], $this->emitter->messages(), $e); } // Clean up unset($this->source[$class]); // Define type $this->debug && fputs(STDERR, $r->type()->toString() . "\n"); $r->executeWith([]); \xp::$cl[$class] = nameof($this) . '://' . $this->instanceId(); return $r->type()->literal(); }
/** * 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 = []; 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) . '\', [' . ($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 \\lang\\IllegalArgumentException(\'Illegal number of arguments\'); }' . '}' . "\n"; } else { $signature = $args = ''; foreach ($method->getParameters() as $param) { $restriction = $param->getTypeRestriction(); $signature .= ', ' . ($restriction ? literal($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; }
public function literal_of_this() { $this->assertEquals(__CLASS__, literal(nameof($this))); }
public function literal_of_this() { $this->assertEquals(self::class, literal(nameof($this))); }
/** * 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 literal($class); } // Ask delegates foreach (self::$delegates as $delegate) { if ($delegate->providesClass($class)) { return $delegate->loadClass0($class); } } throw new ClassNotFoundException($class, self::getLoaders()); }
/** * Resolve a type name * * @param xp.compiler.types.TypeName name * @param bool register * @return xp.compiler.types.Types resolved * @throws xp.compiler.types.ResolveException */ public function resolveType(TypeName $name, $register = true) { if ($name->isArray()) { return new ArrayTypeOf($this->resolveType($name->arrayComponentType(), $register)); } else { if ($name->isMap()) { return new MapTypeOf($this->resolveType($name->mapComponentType(), $register)); } else { if (!$name->isClass()) { return new PrimitiveTypeOf($name); } else { if ($name->isGeneric()) { return new GenericType($this->resolveType(new TypeName($name->name), $register), $name->components); } else { if ($name->isFunction()) { return new FunctionTypeOf($this->resolveType($name->functionReturnType(), $register), $name->components); } } } } } if ($this->declarations) { $decl = $this->declarations[0]; // Keywords: self, parent if ('self' === $name->name || $name->name === $decl->name->name) { return $this->resolved['self']; } else { if ('parent' === $name->name) { return $this->resolved['parent']; } } // See if this type is part of our generic type, return a place holder foreach ($decl->name->components as $component) { if ($component->equals($name)) { return new TypeReference($name, Types::UNKNOWN_KIND); } } // Fall through } $normalized = strtr($name->name, '\\', '.'); if ('xp' === $normalized) { return new TypeReference($name, Types::UNKNOWN_KIND); } else { if (0 === strncmp('php.', $normalized, 4)) { return new TypeReflection(new XPClass(substr($normalized, strrpos($normalized, '.') + 1))); } else { if (strpos($normalized, '.')) { $qualified = $normalized; } else { if (isset($this->imports[$normalized])) { $qualified = $this->imports[$normalized]; } else { $lookup = $this->package ? array_merge($this->packages, [$this->package->name]) : array_merge($this->packages, [null]); try { $qualified = $this->task->locateClass($lookup, $normalized); } catch (\lang\ElementNotFoundException $e) { throw new ResolveException('Cannot resolve ' . $name->toString(), 423, $e); } } } } } // Locate class. If the classloader already knows this class, // we can simply use this class. TODO: Use specialized // JitClassLoader? if (!$this->resolved->containsKey($qualified)) { if (class_exists(literal($qualified), false) || interface_exists(literal($qualified), false) || ClassLoader::getDefault()->providesClass($qualified)) { try { $this->resolved[$qualified] = new TypeReflection(XPClass::forName($qualified)); } catch (\lang\Throwable $e) { throw new ResolveException('Class loader error for ' . $name->toString() . ': ' . $e->getMessage(), 507, $e); } } else { try { $type = $this->task->newSubTask($qualified)->run($this); } catch (\xp\compiler\CompilationException $e) { throw new ResolveException('Cannot resolve ' . $name->toString(), 424, $e); } catch (\lang\Throwable $e) { throw new ResolveException('Cannot resolve ' . $name->toString(), 507, $e); } $this->resolved[$qualified] = $type; } } $register && ($this->used[$qualified] = true); return $this->resolved[$qualified]; }
public function reflectedNameOfClass() { $class = $this->fixture->getClass(); $this->assertEquals('net\\xp_framework\\unittest\\core\\generics\\Lookup··þstring¸unittest¦TestCase', literal($class->getName())); }
/** * Returns an array containing class objects representing all the * public classes * * @return lang.XPClass[] class objects */ public static function getClasses() { foreach (\xp::$cl as $class => $loader) { $ret[] = new self(literal($class)); } return $ret; }
/** * Constructor * * @param string rootName default 'document' */ public function __construct($rootName = 'document') { $this->root = new Node($rootName); $this->nodeType = literal('xml.Node'); }
public function can_create_from_method_and_parameter() { $method = $this->method(null, '($arg)'); new Parameter($method, new \ReflectionParameter([literal($method->declaredIn()->name()), 'fixture'], 0)); }
/** Returns all loaded classes */ public static function getClasses() : \Traversable { foreach (\xp::$cl as $class => $loader) { (yield new self(literal($class))); } }
public function initializerCalled() { $name = 'net.xp_framework.unittest.reflection.LoaderTestClass'; if (class_exists(literal($name), false)) { return $this->fail('Class "' . $name . '" may not exist!'); } $this->assertTrue(ClassLoader::getDefault()->loadClass($name)->getMethod('initializerCalled')->invoke(null)); }
public function packageClassInsidePackage() { $class = self::define('package class', 'PackageClassInPackage', null, '{ }', ['package demo;']); $this->assertEquals('demo.SourcePackageClassInPackage', $class->getName()); $this->assertEquals('demo\\SourcePackageClassInPackage', literal($class->getName())); }
/** * Returns a verified function instance for a given arg and method. * * @param var $arg Either a string referencing a class or an object * @param string $method * @param function(string): var $false A function to return when verification fails * @param bool $return Whether to return the closure, or TRUE * @return php.Closure */ protected function verifiedMethod($arg, $method, $false, $return) { if ('new' === $method) { $class = literal($arg); if (method_exists($class, '__construct')) { $r = new \ReflectionMethod($class, '__construct'); if (!$this->verify($r, $this->signature, $false, $r->getDeclaringClass())) { return false; } } else { if (!$this->returns->isAssignableFrom(new XPClass($class))) { return $false('Class type mismatch'); } } $c = new \ReflectionClass($class); if (!$c->isInstantiable()) { return $false($arg . ' cannot be instantiated'); } return $return ? function () use($c) { return $c->newInstanceArgs(func_get_args()); } : true; } else { if (is_string($arg) && is_string($method)) { $class = literal($arg); if (!method_exists($class, $method)) { return $false('Method ' . $arg . '::' . $method . ' does not exist'); } $r = new \ReflectionMethod($class, $method); if ($r->isStatic()) { if ($this->verify($r, $this->signature, $false, $r->getDeclaringClass())) { return $return ? $r->getClosure(null) : true; } } else { if (null === $this->signature) { $verify = null; } else { if (empty($this->signature) || !$this->signature[0]->isAssignableFrom(new XPClass($class))) { return $false('Method ' . $arg . '::' . $method . ' requires instance of class as first parameter'); } $verify = array_slice($this->signature, 1); } if ($this->verify($r, $verify, $false, $r->getDeclaringClass())) { return $return ? function () use($r) { $args = func_get_args(); $self = array_shift($args); try { return $r->invokeArgs($self, $args); } catch (\ReflectionException $e) { throw new IllegalArgumentException($e->getMessage()); } } : true; } } } else { if (is_object($arg) && is_string($method)) { if (!method_exists($arg, $method)) { return $false('Method ' . nameof($arg) . '::' . $method . ' does not exist'); } $r = new \ReflectionMethod($arg, $method); if ($this->verify($r, $this->signature, $false, $r->getDeclaringClass())) { return $return ? $r->getClosure($arg) : true; } } else { return $false('Array argument must either be [string, string] or an [object, string]'); } } } return $false('Verifying method failed'); }
static function reflect($type) { return literal($type); }