/** * Returns an annotation value. * @return string|NULL */ public static function parseAnnotation(\Reflector $ref, $name) { static $ok; if (!$ok) { if (!(new \ReflectionMethod(__METHOD__))->getDocComment()) { throw new Nette\InvalidStateException('You have to enable phpDoc comments in opcode cache.'); } $ok = TRUE; } if ($ref->getDocComment() && preg_match("#[\\s*]@{$name}(?:\\s++([^@]\\S*)?|\$)#", trim($ref->getDocComment(), '/*'), $m)) { return isset($m[1]) ? $m[1] : ''; } }
/** * Parse the annotations for a given Reflector. * Annotations are derived from doc comments, and are similar to Java's. * * Annotation syntax is simple: * * :foo = expr * * Where 'expr' is a valid JSON expression containing no new lines. * We also support single values, not nested in arrays/objects. * You can't use any null expressions - this would be seen as a syntax * error. You can, of course, create arrays/objects containing nulls. * * It's also valid to do: * * :foo * * Which is simply a shortcut for * * :foo = true * * The JSON is subject to whatever nuances affect PHP's json_decode(). * Particularly, string keys must always be enclosed in quotes, and * all string quoting must be done with double quotes. * * Example usage: * * :requires_super_user = true * :requires_privileges = { "foo": "crude" } * * You can build up arrays on separate lines for clarity: * * :extensions[] = { "name": "Extension1", "param": "foo" } * :extensions[] = { "name": "Extension2", "param": "bar" } * * @todo this method should cache its results as the builder hammers it pretty hard * * @param $r <tt>Reflector</tt> for which to parse annotations * @return associative array of annotations for <tt>$r</tt> */ public static function parse(\Reflector $r) { $comment = $r->getDocComment(); if (strlen($comment) == 0 || strpos($comment, ':') === false) { return array(); } $annotations = array(); preg_match_all('/\\*\\s+:(\\w+)(\\[\\])?\\s*(=\\s*(.*))?$/m', $comment, $matches, PREG_SET_ORDER); foreach ($matches as $m) { if (!isset($m[4])) { $decode = true; } else { $json = trim($m[4]); if ($json[0] == '[' || $json[0] == '{') { $decode = json_decode($json, true); } else { $decode = json_decode('[' . $json . ']', true); if (is_array($decode)) { $decode = $decode[0]; } } } if ($decode === null) { throw new Error_Syntax("Invalid JSON fragment: {$json}"); } if ($m[2] == '[]') { $annotations[$m[1]][] = $decode; } else { $annotations[$m[1]] = $decode; } } return $annotations; }
/** * @param \Reflector $reflection * @param string $type * If we are not reflecting the class itself, specify "Method", "Property", etc. * * @return array */ public static function getCodeDocs($reflection, $type = NULL) { $docs = self::parseDocBlock($reflection->getDocComment()); // Recurse into parent functions if (isset($docs['inheritDoc'])) { unset($docs['inheritDoc']); $newReflection = NULL; try { if ($type) { $name = $reflection->getName(); $reflectionClass = $reflection->getDeclaringClass()->getParentClass(); if ($reflectionClass) { $getItem = "get{$type}"; $newReflection = $reflectionClass->{$getItem}($name); } } else { $newReflection = $reflection->getParentClass(); } } catch (\ReflectionException $e) { } if ($newReflection) { // Mix in $additionalDocs = self::getCodeDocs($newReflection, $type); if (!empty($docs['comment']) && !empty($additionalDocs['comment'])) { $docs['comment'] .= "\n\n" . $additionalDocs['comment']; } $docs += $additionalDocs; } } return $docs; }
function getAnnotation(Reflector $ref) { $doc = $ref->getDocComment(); $annotations = array(); if ($doc !== false) { $pattern = '/@\\s*(\\w+)\\s*(?:\\((.+)\\))?/i'; if (preg_match($pattern, $doc)) { preg_match_all($pattern, $doc, $annotation_matches); for ($i = 0; $i < count($annotation_matches[0]); $i++) { if (class_exists($annotation_matches[1][$i])) { $_class = new $annotation_matches[1][$i](); if ($_class instanceof Annotation) { $annotations[$annotation_matches[1][$i]] = $_class; if (!empty($annotation_matches[2][$i]) && preg_match('/^(?:\\s*\\w+\\s*=\\s*\\w+\\s*,?)+$/i', $annotation_matches[2][$i])) { preg_match_all('/(\\w+)\\s*=\\s*(\\w+)\\s*,?/i', $annotation_matches[2][$i], $annotation_param_matches); for ($j = 0; $j < count($annotation_param_matches[0]); $j++) { $_property = $annotation_param_matches[1][$j]; if (property_exists($_class, $_property)) { $_class->{$_property} = $annotation_param_matches[2][$j]; } } } } } } } } return $annotations; }
/** * Returns the first line of docblock. * * @param \Reflector $reflection * @return string */ protected function parseDocCommentSummary($reflection) { $docLines = preg_split('~\\R~u', $reflection->getDocComment()); if (isset($docLines[1])) { return trim($docLines[1], "\t *"); } return ''; }
/** * create an annotation from the given reflection * * @param \Reflector $reflection */ public function __construct(\Reflector $reflection) { $this->reflection = $reflection; if ($docblock = $reflection->getDocComment()) { $this->rdocblock = new ReflectionDocBlock($docblock); } //if }
/** * @param \Reflector $reflected * @return string */ public function getDocCommentText(\Reflector $reflected) { $comment = $reflected->getDocComment(); // Remove PHPDoc $comment = preg_replace('/^\\s+\\* @[\\w0-9]+.*/msi', '', $comment); // let's clean the doc block $comment = str_replace('/**', '', $comment); $comment = str_replace('*/', '', $comment); $comment = preg_replace('/^\\s*\\* ?/m', '', $comment); return trim($comment); }
function get_comment(Reflector $reflector) { $comments = explode("\n", $reflector->getDocComment()); foreach ($comments as $line) { $nameStart = strpos($line, '@desc: '); if (FALSE === $nameStart) { continue; } else { return trim(substr($line, $nameStart + 6)); } } return 'No description available!'; }
/** * Returns annotations. * @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty * @return array */ public static function getAll(\Reflector $r) { if ($r instanceof \ReflectionClass) { $type = $r->getName(); $member = ''; } elseif ($r instanceof \ReflectionMethod) { $type = $r->getDeclaringClass()->getName(); $member = $r->getName(); } else { $type = $r->getDeclaringClass()->getName(); $member = '$' . $r->getName(); } if (!self::$useReflection) { // auto-expire cache $file = $r instanceof \ReflectionClass ? $r->getFileName() : $r->getDeclaringClass()->getFileName(); // will be used later if ($file && isset(self::$timestamps[$file]) && self::$timestamps[$file] !== filemtime($file)) { unset(self::$cache[$type]); } unset(self::$timestamps[$file]); } if (isset(self::$cache[$type][$member])) { // is value cached? return self::$cache[$type][$member]; } if (self::$useReflection === NULL) { // detects whether is reflection available $self_reflection = new \ReflectionClass(__CLASS__); self::$useReflection = (bool) $self_reflection->getDocComment(); } if (self::$useReflection) { return self::$cache[$type][$member] = self::parseComment($r->getDocComment()); } else { if (self::$cache === NULL) { self::$cache = (array) self::getCache()->offsetGet('list'); self::$timestamps = isset(self::$cache['*']) ? self::$cache['*'] : array(); } if (!isset(self::$cache[$type]) && $file) { self::$cache['*'][$file] = filemtime($file); self::parseScript($file); self::getCache()->save('list', self::$cache); } if (isset(self::$cache[$type][$member])) { return self::$cache[$type][$member]; } else { return self::$cache[$type][$member] = array(); } } }
/** * @param Reflector $reflector * * @return array */ private function getAnnotations(Reflector $reflector) { $annotations = explode(PHP_EOL, $reflector->getDocComment()); $annotations = array_map(array($this, 'cleanMultipleComment'), $annotations); return array_filter($annotations); }
/** * Returns the groups for a test class or method. * * @param Reflector $reflector * @param array $groups * @return array * @since Method available since Release 3.2.0 */ public static function getGroups(Reflector $reflector, array $groups = array()) { $docComment = $reflector->getDocComment(); if (preg_match_all('/@group\\s+([a-zA-Z0-9._-]+)/', $docComment, $matches)) { $groups = array_unique(array_merge($groups, $matches[1])); } return $groups; }
function getDocstring(\Reflector $refl) { $doc_comment = $refl->getDocComment(); if ($doc_comment) { if (preg_match('|/[*][*]\\s*\\n\\s*[*]\\s*(.*)$|m', $doc_comment, $matches)) { return $matches[1]; } } }
/** * Parse the DocBlock of a reflection object. * * @param \Reflector $reflection * @return \Tbs\DocBlock\Collection * @throws \Tbs\DocBlock\Exception */ protected static function of(\Reflector $reflection) { $docComment = $reflection->getDocComment(); if (!strlen($docComment)) { throw new \Tbs\DocBlock\Exception('Invalid DocBlock'); } return new Collection($docComment); }
/** * Returns an annotation value. * @return array|FALSE */ public static function parseAnnotation(\Reflector $ref, $name) { if (!preg_match_all("#[\\s*]@{$name}(?:\\(\\s*([^)]*)\\s*\\))?#", $ref->getDocComment(), $m)) { return FALSE; } $res = array(); foreach ($m[1] as $s) { $arr = $s === '' ? array(TRUE) : preg_split('#\\s*,\\s*#', $s, -1, PREG_SPLIT_NO_EMPTY); $res = array_merge($res, $arr); } return $res; }
private function parseAnnotations(\Reflector $reflector) { $rules = new ParserRules(); $annotations = (new Parser($reflector->getDocComment(), $rules))->parse(); return $annotations; }
/** * * @param \Reflector $reflector * @return \Wispira\Framework\Container\Annotation\Annotations */ public function getReflectorAnnotations(\Reflector $reflector) : Annotations { $comment = $reflector->getDocComment(); return $this->getAnnotations($comment); }
/** * Returns annotations. * @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty * @return array */ public static function getAll(\Reflector $r) { if ($r instanceof \ReflectionClass) { $type = $r->getName(); $member = 'class'; } elseif ($r instanceof \ReflectionMethod) { $type = $r->getDeclaringClass()->getName(); $member = $r->getName(); } else { $type = $r->getDeclaringClass()->getName(); $member = '$' . $r->getName(); } if (!self::$useReflection) { // auto-expire cache $file = $r instanceof \ReflectionClass ? $r->getFileName() : $r->getDeclaringClass()->getFileName(); // will be used later if ($file && isset(self::$timestamps[$file]) && self::$timestamps[$file] !== filemtime($file)) { unset(self::$cache[$type]); } unset(self::$timestamps[$file]); } if (isset(self::$cache[$type][$member])) { // is value cached? return self::$cache[$type][$member]; } if (self::$useReflection === NULL) { // detects whether is reflection available self::$useReflection = (bool) ClassType::from(__CLASS__)->getDocComment(); } if (self::$useReflection) { $annotations = self::parseComment($r->getDocComment()); } else { if (!self::$cacheStorage) { // trigger_error('Set a cache storage for annotations parser via Nette\Reflection\AnnotationParser::setCacheStorage().', E_USER_WARNING); self::$cacheStorage = new Nette\Caching\Storages\DevNullStorage(); } $outerCache = new Nette\Caching\Cache(self::$cacheStorage, 'Nette.Reflection.Annotations'); if (self::$cache === NULL) { self::$cache = (array) $outerCache->load('list'); self::$timestamps = isset(self::$cache['*']) ? self::$cache['*'] : array(); } if (!isset(self::$cache[$type]) && $file) { self::$cache['*'][$file] = filemtime($file); foreach (self::parsePhp(file_get_contents($file)) as $class => $info) { foreach ($info as $prop => $comment) { if ($prop !== 'use') { self::$cache[$class][$prop] = self::parseComment($comment); } } } $outerCache->save('list', self::$cache); } if (isset(self::$cache[$type][$member])) { $annotations = self::$cache[$type][$member]; } else { $annotations = array(); } } if ($r instanceof \ReflectionMethod && !$r->isPrivate() && (!$r->isConstructor() || !empty($annotations['inheritdoc'][0]))) { try { $inherited = self::getAll(new \ReflectionMethod(get_parent_class($type), $member)); } catch (\ReflectionException $e) { try { $inherited = self::getAll($r->getPrototype()); } catch (\ReflectionException $e) { $inherited = array(); } } $annotations += array_intersect_key($inherited, array_flip(self::$inherited)); } return self::$cache[$type][$member] = $annotations; }
/** * Docblock constructor. * * @param \Reflector $reflector */ public function __construct(\Reflector $reflector) { $this->reflector = $reflector; $this->setComment($reflector->getDocComment()); }
/** * Parses and caches annotations. * @param ReflectionClass|\ReflectionMethod|\ReflectionProperty * @return array */ public static function &init(Reflector $r) { $cache =& self::$cache[$r->getName()][$r instanceof ReflectionClass ? '' : $r->getDeclaringClass()->getName()]; if ($cache !== NULL) { return $cache; } preg_match_all('#@([a-zA-Z0-9_]+)(?:\\(((?>[^\'")]+|\'[^\']*\'|"[^"]*")*)\\))?#', $r->getDocComment(), $matches, PREG_SET_ORDER); $cache = array(); foreach ($matches as $match) { if (isset($match[2])) { preg_match_all('#[,\\s](?>([a-zA-Z0-9_]+)\\s*=\\s*)?([^\'",\\s][^,]*|\'[^\']*\'|"[^"]*")#', ',' . $match[2], $matches, PREG_SET_ORDER); $items = array(); $key = ''; $val = TRUE; foreach ($matches as $m) { list(, $key, $val) = $m; if ($val[0] === "'" || $val[0] === '"') { $val = substr($val, 1, -1); } elseif (strcasecmp($val, 'true') === 0) { $val = TRUE; } elseif (strcasecmp($val, 'false') === 0) { $val = FALSE; } elseif (is_numeric($val)) { $val = 1 * $val; } if ($key === '') { $items[] = $val; } else { $items[$key] = $val; } } $items = count($items) < 2 && $key === '' ? $val : new ArrayObject($items, ArrayObject::ARRAY_AS_PROPS); } else { $items = TRUE; } $cache[$match[1]][] = $items; } return $cache; }
/** * Returns an annotation value. * @return array|FALSE */ public static function parseAnnotation(\Reflector $ref, $name) { if (!preg_match_all('#[\\s*]@' . preg_quote($name, '#') . '(?:\\(\\s*([^)]*)\\s*\\)|\\s|$)#', $ref->getDocComment(), $m)) { return FALSE; } static $tokens = ['true' => TRUE, 'false' => FALSE, 'null' => NULL]; $res = []; foreach ($m[1] as $s) { foreach (preg_split('#\\s*,\\s*#', $s, -1, PREG_SPLIT_NO_EMPTY) ?: ['true'] as $item) { $res[] = array_key_exists($tmp = strtolower($item), $tokens) ? $tokens[$tmp] : $item; } } return $res; }
/** * Returns the groups for a test class or method. * * @param Reflector $reflector * @param array $groups * @return array * @access public * @static * @since Method available since Release 3.2.0 */ public static function getGroups(Reflector $reflector, array $groups = array()) { $docComment = $reflector->getDocComment(); if (preg_match_all('/@group[\\s]+([\\.\\w]+)/', $docComment, $matches)) { $groups = array_merge($groups, $matches[1]); } return $groups; }
static function getAll(Reflector $r) { if ($r instanceof ReflectionClass) { $type = $r->getName(); $member = ''; } elseif ($r instanceof ReflectionMethod) { $type = $r->getDeclaringClass()->getName(); $member = $r->getName(); } else { $type = $r->getDeclaringClass()->getName(); $member = '$' . $r->getName(); } if (!self::$useReflection) { $file = $r instanceof ReflectionClass ? $r->getFileName() : $r->getDeclaringClass()->getFileName(); if ($file && isset(self::$timestamps[$file]) && self::$timestamps[$file] !== filemtime($file)) { unset(self::$cache[$type]); } unset(self::$timestamps[$file]); } if (isset(self::$cache[$type][$member])) { return self::$cache[$type][$member]; } if (self::$useReflection === NULL) { self::$useReflection = (bool) NClassReflection::from(__CLASS__)->getDocComment(); } if (self::$useReflection) { return self::$cache[$type][$member] = self::parseComment($r->getDocComment()); } else { if (self::$cache === NULL) { self::$cache = (array) self::getCache()->offsetGet('list'); self::$timestamps = isset(self::$cache['*']) ? self::$cache['*'] : array(); } if (!isset(self::$cache[$type]) && $file) { self::$cache['*'][$file] = filemtime($file); self::parseScript($file); self::getCache()->save('list', self::$cache); } if (isset(self::$cache[$type][$member])) { return self::$cache[$type][$member]; } else { return self::$cache[$type][$member] = array(); } } }
static function getAll(\Reflector $r) { if ($r instanceof \ReflectionClass) { $type = $r->getName(); $member = ''; } elseif ($r instanceof \ReflectionMethod) { $type = $r->getDeclaringClass()->getName(); $member = $r->getName(); } else { $type = $r->getDeclaringClass()->getName(); $member = '$' . $r->getName(); } if (!self::$useReflection) { $file = $r instanceof \ReflectionClass ? $r->getFileName() : $r->getDeclaringClass()->getFileName(); if ($file && isset(self::$timestamps[$file]) && self::$timestamps[$file] !== filemtime($file)) { unset(self::$cache[$type]); } unset(self::$timestamps[$file]); } if (isset(self::$cache[$type][$member])) { return self::$cache[$type][$member]; } if (self::$useReflection === NULL) { self::$useReflection = (bool) ClassType::from(__CLASS__)->getDocComment(); } if (self::$useReflection) { $annotations = self::parseComment($r->getDocComment()); } else { if (!self::$cacheStorage) { self::$cacheStorage = new Nette\Caching\Storages\DevNullStorage(); } $outerCache = new Nette\Caching\Cache(self::$cacheStorage, 'Nette.Reflection.Annotations'); if (self::$cache === NULL) { self::$cache = (array) $outerCache->offsetGet('list'); self::$timestamps = isset(self::$cache['*']) ? self::$cache['*'] : array(); } if (!isset(self::$cache[$type]) && $file) { self::$cache['*'][$file] = filemtime($file); self::parseScript($file); $outerCache->save('list', self::$cache); } if (isset(self::$cache[$type][$member])) { $annotations = self::$cache[$type][$member]; } else { $annotations = array(); } } if ($r instanceof \ReflectionMethod && !$r->isPrivate() && (!$r->isConstructor() || !empty($annotations['inheritdoc'][0]))) { try { $inherited = self::getAll(new \ReflectionMethod(get_parent_class($type), $member)); } catch (\ReflectionException $e) { try { $inherited = self::getAll($r->getPrototype()); } catch (\ReflectionException $e) { $inherited = array(); } } $annotations += array_intersect_key($inherited, array_flip(self::$inherited)); } return self::$cache[$type][$member] = $annotations; }
/** * Parses the comment block into tags. * @param \Reflector $reflection the comment block * @return array the parsed tags */ protected function parseDocCommentTags($reflection) { $comment = $reflection->getDocComment(); $comment = "@description \n" . strtr(trim(preg_replace('/^\\s*\\**( |\\t)?/m', '', trim($comment, '/'))), "\r", ''); $parts = preg_split('/^\\s*@/m', $comment, -1, PREG_SPLIT_NO_EMPTY); $tags = []; foreach ($parts as $part) { if (preg_match('/^(\\w+)(.*)/ms', trim($part), $matches)) { $name = $matches[1]; if (!isset($tags[$name])) { $tags[$name] = trim($matches[2]); } elseif (is_array($tags[$name])) { $tags[$name][] = trim($matches[2]); } else { $tags[$name] = [$tags[$name], trim($matches[2])]; } } } return $tags; }
/** * @param \Nette\Reflection\ClassType|\Nette\Reflection\Method|\Reflector $refl * @param null $atPos * * @return string */ private static function cleanedPhpDoc(\Reflector $refl, &$atPos = NULL) { return trim(substr($doc = $refl->getDocComment(), $atPos = strpos($doc, '@') - 1), '* /'); }
protected function setReflector(\Reflector $oReflection) { $this->Reflector = $oReflection; $this->setDoc($oReflection->getDocComment()); }
/** * returns doc comment for given reflector * * @internal * @param \Reflector $reflector * @return string * @throws \ReflectionException * @since 5.3.0 */ function docComment(\Reflector $reflector) : string { if ($reflector instanceof \ReflectionClass || $reflector instanceof \ReflectionFunctionAbstract || $reflector instanceof \ReflectionProperty) { $docComment = $reflector->getDocComment(); return false !== $docComment ? $docComment : ''; } if ($reflector instanceof \ReflectionParameter) { return docComment($reflector->getDeclaringFunction()); } throw new \ReflectionException('Can not retrieve doc comment for ' . get_class($reflector)); }
/** * @param \Reflector $reflector * @return DocBlock */ public function __construct(\Reflector $reflector) { $this->setBlock($reflector->getDocComment()); }
/** * Returns full description from the docblock. * * @param \Reflector $reflection * @return string */ protected function parseDocCommentDetail($reflection) { $comment = strtr(trim(preg_replace('/^\\s*\\**( |\\t)?/m', '', trim($reflection->getDocComment(), '/'))), "\r", ''); if (preg_match('/^\\s*@\\w+/m', $comment, $matches, PREG_OFFSET_CAPTURE)) { $comment = trim(substr($comment, 0, $matches[0][1])); } if ($comment !== '') { return rtrim(Console::renderColoredString(Console::markdownToAnsi($comment))); } return ''; }
/** * Returns annotations. * @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty * @return array */ public static function getAll(\Reflector $r) { if ($r instanceof \ReflectionClass) { $type = $r->getName(); $member = 'class'; $file = $r->getFileName(); } elseif ($r instanceof \ReflectionMethod) { $type = $r->getDeclaringClass()->getName(); $member = $r->getName(); $file = $r->getFileName(); } elseif ($r instanceof \ReflectionFunction) { $type = NULL; $member = $r->getName(); $file = $r->getFileName(); } else { $type = $r->getDeclaringClass()->getName(); $member = '$' . $r->getName(); $file = $r->getDeclaringClass()->getFileName(); } if (!self::$useReflection) { // auto-expire cache if ($file && isset(self::$timestamps[$file]) && self::$timestamps[$file] !== filemtime($file)) { unset(self::$cache[$type]); } unset(self::$timestamps[$file]); } if (isset(self::$cache[$type][$member])) { // is value cached? return self::$cache[$type][$member]; } if (self::$useReflection === NULL) { // detects whether is reflection available self::$useReflection = (bool) ClassType::from(__CLASS__)->getDocComment(); } if (self::$useReflection) { $annotations = self::parseComment($r->getDocComment()); } else { $outerCache = self::getCache(); if (self::$cache === NULL) { self::$cache = (array) $outerCache->load('list'); self::$timestamps = isset(self::$cache['*']) ? self::$cache['*'] : []; } if (!isset(self::$cache[$type]) && $file) { self::$cache['*'][$file] = filemtime($file); foreach (static::parsePhp(file_get_contents($file)) as $class => $info) { foreach ($info as $prop => $comment) { if ($prop !== 'use') { self::$cache[$class][$prop] = self::parseComment($comment); } } } $outerCache->save('list', self::$cache); } if (isset(self::$cache[$type][$member])) { $annotations = self::$cache[$type][$member]; } else { $annotations = []; } } if ($r instanceof \ReflectionMethod && !$r->isPrivate() && (!$r->isConstructor() || !empty($annotations['inheritdoc'][0]))) { try { $inherited = self::getAll(new \ReflectionMethod(get_parent_class($type), $member)); } catch (\ReflectionException $e) { try { $inherited = self::getAll($r->getPrototype()); } catch (\ReflectionException $e) { $inherited = []; } } $annotations += array_intersect_key($inherited, array_flip(self::$inherited)); } return self::$cache[$type][$member] = $annotations; }