/** * Resolves a class member, which is either a field, a class constant * or the `ClassName::class` syntax, which returns the class' literal. * * @param lang.XPClass $class * @param var[] $token A token as returned by `token_get_all()` * @param string $context * @return var */ protected function memberOf($class, $token, $context) { if (T_VARIABLE === $token[0]) { $field = $class->getField(substr($token[1], 1)); $m = $field->getModifiers(); if ($m & MODIFIER_PUBLIC) { return $field->get(null); } else { if ($m & MODIFIER_PROTECTED && $class->isAssignableFrom($context)) { return $field->setAccessible(true)->get(null); } else { if ($m & MODIFIER_PRIVATE && $class->getName() === $context) { return $field->setAccessible(true)->get(null); } else { throw new IllegalAccessException(sprintf('Cannot access %s field %s::$%s', implode(' ', Modifiers::namesOf($m)), $class->getName(), $field->getName())); } } } } else { if (T_CLASS === $token[0]) { return $class->literal(); } else { return $class->getConstant($token[1]); } } }
/** * Fetch a qname for a class. * * @param lang.XPClass class * @return var xml.QName or NULL if no mapping exists */ public function qnameFor(\lang\XPClass $class) { if (!isset($this->_c2q[$class->getName()])) { return null; } return $this->_qnames[$this->_c2q[$class->getName()]]; }
/** * Locate interface by a given name * * @param lang.XPClass $class * @param string $name * @return lang.XPClass * @throws lang.ElementNotFoundException */ private function interfaceNamed($class, $name) { foreach ($class->getInterfaces() as $iface) { if (strstr($iface->getName(), $name)) { return $iface; } } throw new ElementNotFoundException('Class ' . $class->getName() . ' does not implement ' . $name); }
/** * Creates a new instance of a given class. If the constructor uses * injection, the arguments are compiled from the relevant annotations. * Otherwise, optional constructor arguments may be passed. * * @param lang.XPClass $class * @param [:var] $named Named arguments * @return var * @throws inject.ProvisionException */ public function newInstance(XPClass $class, $named = []) { if ($class->hasConstructor()) { $constructor = $class->getConstructor(); try { return $constructor->newInstance($this->args($constructor, $named)); } catch (TargetInvocationException $e) { throw new ProvisionException('Error creating an instance of ' . $class->getName(), $e->getCause()); } catch (Throwable $e) { throw new ProvisionException('Error creating an instance of ' . $class->getName(), $e); } } else { return $class->newInstance(); } }
/** * Gets class name (and generic components if this class is a * generic definition) * * @param lang.XPClass class * @return string */ protected static function displayNameOf(XPClass $class) { return $class->getName() . ($class->isGenericDefinition() ? '<' . implode(', ', $class->genericComponents()) . '>' : ''); }
/** * Show usage * * @param lang.XPClass class */ public static function showUsage(XPClass $class) { // Description if (null !== ($comment = $class->getComment())) { self::$err->writeLine(self::textOf($comment)); self::$err->writeLine(str_repeat('=', 72)); } $extra = $details = $positional = []; foreach ($class->getMethods() as $method) { if (!$method->hasAnnotation('arg')) { continue; } $arg = $method->getAnnotation('arg'); $name = strtolower(preg_replace('/^set/', '', $method->getName())); $comment = self::textOf($method->getComment()); if (0 == $method->numParameters()) { $optional = true; } else { list($first, ) = $method->getParameters(); $optional = $first->isOptional(); } if (isset($arg['position'])) { $details['#' . ($arg['position'] + 1)] = $comment; $positional[$arg['position']] = $name; } else { if (isset($arg['name'])) { $details['--' . $arg['name'] . ' | -' . (isset($arg['short']) ? $arg['short'] : $arg['name'][0])] = $comment; $extra[$arg['name']] = $optional; } else { $details['--' . $name . ' | -' . (isset($arg['short']) ? $arg['short'] : $name[0])] = $comment; $extra[$name] = $optional; } } } // Usage asort($positional); self::$err->write('Usage: $ xpcli ', $class->getName(), ' '); foreach ($positional as $name) { self::$err->write('<', $name, '> '); } foreach ($extra as $name => $optional) { self::$err->write($optional ? '[' : '', '--', $name, $optional ? '] ' : ' '); } self::$err->writeLine(); // Argument details self::$err->writeLine('Arguments:'); foreach ($details as $which => $comment) { self::$err->writeLine('* ', $which, "\n ", str_replace("\n", "\n ", $comment), "\n"); } }
/** * Tries to get class uri via reflection * * @param lang.XPClass class The class to return the URI for * @return string */ private function uriFor(XPClass $class) { return $class->getClassLoader()->classUri($class->getName()); }