no message
This commit is contained in:
+40
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "nette/reflection",
|
||||
"description": "Nette Reflection: docblock annotations parser and common reflection classes",
|
||||
"keywords": ["nette", "annotation", "reflection"],
|
||||
"homepage": "https://nette.org",
|
||||
"license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "David Grudl",
|
||||
"homepage": "https://davidgrudl.com"
|
||||
},
|
||||
{
|
||||
"name": "Nette Community",
|
||||
"homepage": "https://nette.org/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"ext-tokenizer": "*",
|
||||
"nette/caching": "^2.2 || ^3.0",
|
||||
"nette/utils": "^2.4 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nette/di": "^2.4 || ^3.0",
|
||||
"nette/tester": "^2.0",
|
||||
"tracy/tracy": "^2.4"
|
||||
},
|
||||
"conflict": {
|
||||
"nette/nette": "<2.2"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": ["src/"]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
How to contribute & use the issue tracker
|
||||
=========================================
|
||||
|
||||
Nette welcomes your contributions. There are several ways to help out:
|
||||
|
||||
* Create an issue on GitHub, if you have found a bug
|
||||
* Write test cases for open bug issues
|
||||
* Write fixes for open bug/feature issues, preferably with test cases included
|
||||
* Contribute to the [documentation](https://nette.org/en/writing)
|
||||
|
||||
Issues
|
||||
------
|
||||
|
||||
Please **do not use the issue tracker to ask questions**. We will be happy to help you
|
||||
on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette).
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you up for more
|
||||
information. Please try to be as detailed as possible in your report.
|
||||
|
||||
**Feature requests** are welcome. But take a moment to find out whether your idea
|
||||
fits with the scope and aims of the project. It's up to *you* to make a strong
|
||||
case to convince the project's developers of the merits of this feature.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing).
|
||||
|
||||
The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them.
|
||||
|
||||
Please do not fix whitespace, format code, or make a purely cosmetic patch.
|
||||
|
||||
Thanks! :heart:
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
Licenses
|
||||
========
|
||||
|
||||
Good news! You may use Nette Framework under the terms of either
|
||||
the New BSD License or the GNU General Public License (GPL) version 2 or 3.
|
||||
|
||||
The BSD License is recommended for most projects. It is easy to understand and it
|
||||
places almost no restrictions on what you can do with the framework. If the GPL
|
||||
fits better to your project, you can use the framework under this license.
|
||||
|
||||
You don't have to notify anyone which license you are using. You can freely
|
||||
use Nette Framework in commercial projects as long as the copyright header
|
||||
remains intact.
|
||||
|
||||
Please be advised that the name "Nette Framework" is a protected trademark and its
|
||||
usage has some limitations. So please do not use word "Nette" in the name of your
|
||||
project or top-level domain, and choose a name that stands on its own merits.
|
||||
If your stuff is good, it will not take long to establish a reputation for yourselves.
|
||||
|
||||
|
||||
New BSD License
|
||||
---------------
|
||||
|
||||
Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of "Nette Framework" nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
This software is provided by the copyright holders and contributors "as is" and
|
||||
any express or implied warranties, including, but not limited to, the implied
|
||||
warranties of merchantability and fitness for a particular purpose are
|
||||
disclaimed. In no event shall the copyright owner or contributors be liable for
|
||||
any direct, indirect, incidental, special, exemplary, or consequential damages
|
||||
(including, but not limited to, procurement of substitute goods or services;
|
||||
loss of use, data, or profits; or business interruption) however caused and on
|
||||
any theory of liability, whether in contract, strict liability, or tort
|
||||
(including negligence or otherwise) arising in any way out of the use of this
|
||||
software, even if advised of the possibility of such damage.
|
||||
|
||||
|
||||
GNU General Public License
|
||||
--------------------------
|
||||
|
||||
GPL licenses are very very long, so instead of including them here we offer
|
||||
you URLs with full text:
|
||||
|
||||
- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html)
|
||||
- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html)
|
||||
Vendored
+89
@@ -0,0 +1,89 @@
|
||||
Nette PHP Reflection
|
||||
====================
|
||||
|
||||
[](https://packagist.org/packages/nette/reflection)
|
||||
[](https://travis-ci.org/nette/reflection)
|
||||
[](https://coveralls.io/github/nette/reflection?branch=master)
|
||||
[](https://github.com/nette/reflection/releases)
|
||||
[](https://github.com/nette/reflection/blob/master/license.md)
|
||||
|
||||
Install it using Composer:
|
||||
|
||||
```
|
||||
composer require nette/reflection
|
||||
```
|
||||
|
||||
The last stable release requires PHP version 5.6 or newer (is compatible with PHP 7.0 and 7.1).
|
||||
|
||||
If you need to find every information about any class, reflection is the right tool to do it. You can easily find out which methods does any class have, what parameters do those methods accept, etc.
|
||||
|
||||
```php
|
||||
// getting PDO class reflection
|
||||
$classReflection = new Nette\Reflection\ClassType('PDO');
|
||||
|
||||
// getting PDO::query method reflection
|
||||
$methodReflection = new Nette\Reflection\Method('PDO', 'query');
|
||||
```
|
||||
|
||||
Annotations
|
||||
-----------
|
||||
|
||||
Reflection has really a lot to do with annotations. The annotations are written into phpDoc comments (two opening asterisks are mandatory!) and start with `@`. You can annotate classes, variables and methods:
|
||||
|
||||
```php
|
||||
/**
|
||||
* @author John Doe
|
||||
* @author Tomas Marny
|
||||
* @secured
|
||||
*/
|
||||
class FooClass
|
||||
{
|
||||
/** @Persistent */
|
||||
public $foo;
|
||||
|
||||
/** @User(loggedIn, role=Admin) */
|
||||
public function bar() {}
|
||||
}
|
||||
```
|
||||
|
||||
In the code there are these annotations:
|
||||
|
||||
- `@author John Doe` - string, contains text value `'John Doe'`
|
||||
- `@Persistent` - boolean, its presence means `true`
|
||||
- `@User(loggedIn, role=Admin)` - contains associative `array('loggedIn', 'role' => 'Admin')`
|
||||
|
||||
|
||||
The existence of a class annotation can be checked via `hasAnnotation()` method:
|
||||
|
||||
|
||||
```php
|
||||
$fooReflection = new Nette\Reflection\ClassType('FooClass');
|
||||
$fooReflection->hasAnnotation('author'); // returns true
|
||||
$fooReflection->hasAnnotation('copyright'); // returns false
|
||||
```
|
||||
|
||||
Values can be acquired with `getAnnotation()`:
|
||||
|
||||
```php
|
||||
$fooReflection->getAnnotation('author'); // returns string 'Tomas Marny'
|
||||
|
||||
$fooReflection->getMethod('bar')->getAnnotation('User');
|
||||
// returns array('loggedIn', 'role' => 'Admin')
|
||||
```
|
||||
|
||||
.[caution]
|
||||
Previous definitions are overwritten with the latter ones, sou you will always get the last one.
|
||||
|
||||
All annotations can be obtained with `getAnnotations()`:
|
||||
|
||||
```
|
||||
array(3) {
|
||||
"author" => array(2) {
|
||||
0 => string(8) "John Doe"
|
||||
1 => string(11) "Tomas Marny"
|
||||
}
|
||||
"secured" => array(1) {
|
||||
0 => bool(true)
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Bridges\ReflectionDI;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Extension for Nette DI.
|
||||
*/
|
||||
class ReflectionExtension extends Nette\DI\CompilerExtension
|
||||
{
|
||||
/** @var bool */
|
||||
private $debugMode;
|
||||
|
||||
|
||||
public function __construct($debugMode = false)
|
||||
{
|
||||
$this->debugMode = $debugMode;
|
||||
}
|
||||
|
||||
|
||||
public function afterCompile(Nette\PhpGenerator\ClassType $class)
|
||||
{
|
||||
$class->getMethod('initialize')
|
||||
->addBody('Nette\Reflection\AnnotationsParser::setCacheStorage($this->getByType(Nette\Caching\IStorage::class));')
|
||||
->addBody('Nette\Reflection\AnnotationsParser::$autoRefresh = ?;', [$this->debugMode]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Basic annotation implementation.
|
||||
*/
|
||||
class Annotation implements IAnnotation
|
||||
{
|
||||
use Nette\SmartObject;
|
||||
|
||||
public function __construct(array $values)
|
||||
{
|
||||
foreach ($values as $k => $v) {
|
||||
$this->$k = $v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns default annotation.
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,419 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
use Nette\Utils\Strings;
|
||||
|
||||
|
||||
/**
|
||||
* Annotations support for PHP.
|
||||
* @Annotation
|
||||
*/
|
||||
class AnnotationsParser
|
||||
{
|
||||
use Nette\StaticClass;
|
||||
|
||||
/** @internal single & double quoted PHP string */
|
||||
const RE_STRING = '\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"';
|
||||
|
||||
/** @internal identifier */
|
||||
const RE_IDENTIFIER = '[_a-zA-Z\x7F-\xFF][_a-zA-Z0-9\x7F-\xFF-\\\]*';
|
||||
|
||||
/** @var bool */
|
||||
public static $useReflection;
|
||||
|
||||
/** @var bool */
|
||||
public static $autoRefresh = true;
|
||||
|
||||
/** @var array */
|
||||
public static $inherited = ['description', 'param', 'return'];
|
||||
|
||||
/** @var array */
|
||||
private static $cache;
|
||||
|
||||
/** @var array */
|
||||
private static $timestamps;
|
||||
|
||||
/** @var Nette\Caching\IStorage */
|
||||
private static $cacheStorage;
|
||||
|
||||
|
||||
/**
|
||||
* 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 === null) { // detects whether is reflection available
|
||||
self::$useReflection = (bool) ClassType::from(__CLASS__)->getDocComment();
|
||||
}
|
||||
|
||||
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) {
|
||||
$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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expands class name into FQN.
|
||||
* @param string
|
||||
* @return string fully qualified class name
|
||||
* @throws Nette\InvalidArgumentException
|
||||
*/
|
||||
public static function expandClassName($name, \ReflectionClass $reflector)
|
||||
{
|
||||
if (empty($name)) {
|
||||
throw new Nette\InvalidArgumentException('Class name must not be empty.');
|
||||
|
||||
} elseif ($name === 'self') {
|
||||
return $reflector->getName();
|
||||
|
||||
} elseif ($name[0] === '\\') { // already fully qualified
|
||||
return ltrim($name, '\\');
|
||||
}
|
||||
|
||||
$filename = $reflector->getFileName();
|
||||
$parsed = static::getCache()->load($filename, function (&$dp) use ($filename) {
|
||||
if (self::$autoRefresh) {
|
||||
$dp[Nette\Caching\Cache::FILES] = $filename;
|
||||
}
|
||||
return self::parsePhp(file_get_contents($filename));
|
||||
});
|
||||
$uses = array_change_key_case((array) $tmp = &$parsed[$reflector->getName()]['use']);
|
||||
$parts = explode('\\', $name, 2);
|
||||
$parts[0] = strtolower($parts[0]);
|
||||
if (isset($uses[$parts[0]])) {
|
||||
$parts[0] = $uses[$parts[0]];
|
||||
return implode('\\', $parts);
|
||||
|
||||
} elseif ($reflector->inNamespace()) {
|
||||
return $reflector->getNamespaceName() . '\\' . $name;
|
||||
|
||||
} else {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses phpDoc comment.
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
private static function parseComment($comment)
|
||||
{
|
||||
static $tokens = ['true' => true, 'false' => false, 'null' => null, '' => true];
|
||||
|
||||
$res = [];
|
||||
$comment = preg_replace('#^\s*\*\s?#ms', '', trim($comment, '/*'));
|
||||
$parts = preg_split('#^\s*(?=@' . self::RE_IDENTIFIER . ')#m', $comment, 2);
|
||||
|
||||
$description = trim($parts[0]);
|
||||
if ($description !== '') {
|
||||
$res['description'] = [$description];
|
||||
}
|
||||
|
||||
$matches = Strings::matchAll(
|
||||
isset($parts[1]) ? $parts[1] : '',
|
||||
'~
|
||||
(?<=\s|^)@(' . self::RE_IDENTIFIER . ')[ \t]* ## annotation
|
||||
(
|
||||
\((?>' . self::RE_STRING . '|[^\'")@]+)+\)| ## (value)
|
||||
[^(@\r\n][^@\r\n]*|) ## value
|
||||
~xi'
|
||||
);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
list(, $name, $value) = $match;
|
||||
|
||||
if (substr($value, 0, 1) === '(') {
|
||||
$items = [];
|
||||
$key = '';
|
||||
$val = true;
|
||||
$value[0] = ',';
|
||||
while ($m = Strings::match(
|
||||
$value,
|
||||
'#\s*,\s*(?>(' . self::RE_IDENTIFIER . ')\s*=\s*)?(' . self::RE_STRING . '|[^\'"),\s][^\'"),]*)#A')
|
||||
) {
|
||||
$value = substr($value, strlen($m[0]));
|
||||
list(, $key, $val) = $m;
|
||||
$val = rtrim($val);
|
||||
if ($val[0] === "'" || $val[0] === '"') {
|
||||
$val = substr($val, 1, -1);
|
||||
|
||||
} elseif (is_numeric($val)) {
|
||||
$val = 1 * $val;
|
||||
|
||||
} else {
|
||||
$lval = strtolower($val);
|
||||
$val = array_key_exists($lval, $tokens) ? $tokens[$lval] : $val;
|
||||
}
|
||||
|
||||
if ($key === '') {
|
||||
$items[] = $val;
|
||||
|
||||
} else {
|
||||
$items[$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
$value = count($items) < 2 && $key === '' ? $val : $items;
|
||||
|
||||
} else {
|
||||
$value = trim($value);
|
||||
if (is_numeric($value)) {
|
||||
$value = 1 * $value;
|
||||
|
||||
} else {
|
||||
$lval = strtolower($value);
|
||||
$value = array_key_exists($lval, $tokens) ? $tokens[$lval] : $value;
|
||||
}
|
||||
}
|
||||
|
||||
$res[$name][] = is_array($value) ? Nette\Utils\ArrayHash::from($value) : $value;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses PHP file.
|
||||
* @param string
|
||||
* @return array [class => [prop => comment (or 'use' => [alias => class])]
|
||||
* @internal
|
||||
*/
|
||||
public static function parsePhp($code)
|
||||
{
|
||||
if (Strings::match($code, '#//nette' . 'loader=(\S*)#')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tokens = @token_get_all($code);
|
||||
$namespace = $class = $classLevel = $level = $docComment = null;
|
||||
$res = $uses = [];
|
||||
|
||||
while ($token = current($tokens)) {
|
||||
next($tokens);
|
||||
switch (is_array($token) ? $token[0] : $token) {
|
||||
case T_DOC_COMMENT:
|
||||
$docComment = $token[1];
|
||||
break;
|
||||
|
||||
case T_NAMESPACE:
|
||||
$namespace = ltrim(self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]) . '\\', '\\');
|
||||
$uses = [];
|
||||
break;
|
||||
|
||||
case T_CLASS:
|
||||
case T_INTERFACE:
|
||||
case T_TRAIT:
|
||||
if ($name = self::fetch($tokens, T_STRING)) {
|
||||
$class = $namespace . $name;
|
||||
$classLevel = $level + 1;
|
||||
$res[$class] = [];
|
||||
if ($docComment) {
|
||||
$res[$class]['class'] = $docComment;
|
||||
}
|
||||
if ($uses) {
|
||||
$res[$class]['use'] = $uses;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case T_FUNCTION:
|
||||
self::fetch($tokens, '&');
|
||||
if ($level === $classLevel && $docComment && ($name = self::fetch($tokens, T_STRING))) {
|
||||
$res[$class][$name] = $docComment;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_VAR:
|
||||
case T_PUBLIC:
|
||||
case T_PROTECTED:
|
||||
self::fetch($tokens, T_STATIC);
|
||||
if ($level === $classLevel && $docComment && ($name = self::fetch($tokens, T_VARIABLE))) {
|
||||
$res[$class][$name] = $docComment;
|
||||
}
|
||||
break;
|
||||
|
||||
case T_USE:
|
||||
while (!$class && ($name = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]))) {
|
||||
$name = ltrim($name, '\\');
|
||||
if (self::fetch($tokens, '{')) {
|
||||
while ($suffix = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR])) {
|
||||
if (self::fetch($tokens, T_AS)) {
|
||||
$uses[self::fetch($tokens, T_STRING)] = $name . $suffix;
|
||||
} else {
|
||||
$tmp = explode('\\', $suffix);
|
||||
$uses[end($tmp)] = $name . $suffix;
|
||||
}
|
||||
if (!self::fetch($tokens, ',')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} elseif (self::fetch($tokens, T_AS)) {
|
||||
$uses[self::fetch($tokens, T_STRING)] = $name;
|
||||
|
||||
} else {
|
||||
$tmp = explode('\\', $name);
|
||||
$uses[end($tmp)] = $name;
|
||||
}
|
||||
if (!self::fetch($tokens, ',')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case T_CURLY_OPEN:
|
||||
case T_DOLLAR_OPEN_CURLY_BRACES:
|
||||
case '{':
|
||||
$level++;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
if ($level === $classLevel) {
|
||||
$class = $classLevel = null;
|
||||
}
|
||||
$level--;
|
||||
// break omitted
|
||||
case ';':
|
||||
$docComment = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
private static function fetch(&$tokens, $take)
|
||||
{
|
||||
$res = null;
|
||||
while ($token = current($tokens)) {
|
||||
list($token, $s) = is_array($token) ? $token : [$token, $token];
|
||||
if (in_array($token, (array) $take, true)) {
|
||||
$res .= $s;
|
||||
} elseif (!in_array($token, [T_DOC_COMMENT, T_WHITESPACE, T_COMMENT], true)) {
|
||||
break;
|
||||
}
|
||||
next($tokens);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/********************* backend ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function setCacheStorage(Nette\Caching\IStorage $storage)
|
||||
{
|
||||
self::$cacheStorage = $storage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Nette\Caching\IStorage
|
||||
*/
|
||||
public static function getCacheStorage()
|
||||
{
|
||||
if (!self::$cacheStorage) {
|
||||
self::$cacheStorage = new Nette\Caching\Storages\MemoryStorage();
|
||||
}
|
||||
return self::$cacheStorage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Nette\Caching\Cache
|
||||
*/
|
||||
private static function getCache()
|
||||
{
|
||||
return new Nette\Caching\Cache(static::getCacheStorage(), 'Nette.Reflection.Annotations');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Reports information about a class.
|
||||
* @property-read Method $constructor
|
||||
* @property-read Extension $extension
|
||||
* @property-read ClassType[] $interfaces
|
||||
* @property-read Method[] $methods
|
||||
* @property-read ClassType $parentClass
|
||||
* @property-read Property[] $properties
|
||||
* @property-read IAnnotation[][] $annotations
|
||||
* @property-read string $description
|
||||
* @property-read string $name
|
||||
* @property-read bool $internal
|
||||
* @property-read bool $userDefined
|
||||
* @property-read bool $instantiable
|
||||
* @property-read string $fileName
|
||||
* @property-read int $startLine
|
||||
* @property-read int $endLine
|
||||
* @property-read string $docComment
|
||||
* @property-read mixed[] $constants
|
||||
* @property-read string[] $interfaceNames
|
||||
* @property-read bool $interface
|
||||
* @property-read bool $abstract
|
||||
* @property-read bool $final
|
||||
* @property-read int $modifiers
|
||||
* @property-read array $staticProperties
|
||||
* @property-read array $defaultProperties
|
||||
* @property-read bool $iterateable
|
||||
* @property-read string $extensionName
|
||||
* @property-read string $namespaceName
|
||||
* @property-read string $shortName
|
||||
*/
|
||||
class ClassType extends \ReflectionClass
|
||||
{
|
||||
use Nette\SmartObject;
|
||||
|
||||
/**
|
||||
* @param string|object
|
||||
* @return static
|
||||
*/
|
||||
public static function from($class)
|
||||
{
|
||||
return new static($class);
|
||||
}
|
||||
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
public function is($type)
|
||||
{
|
||||
return is_a($this->getName(), $type, true);
|
||||
}
|
||||
|
||||
|
||||
/********************* Reflection layer ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* @return Method|null
|
||||
*/
|
||||
public function getConstructor()
|
||||
{
|
||||
return ($ref = parent::getConstructor()) ? Method::from($this->getName(), $ref->getName()) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Extension|null
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
return ($name = $this->getExtensionName()) ? new Extension($name) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return static[]
|
||||
*/
|
||||
public function getInterfaces()
|
||||
{
|
||||
$res = [];
|
||||
foreach (parent::getInterfaceNames() as $val) {
|
||||
$res[$val] = new static($val);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Method
|
||||
*/
|
||||
public function getMethod($name)
|
||||
{
|
||||
return new Method($this->getName(), $name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Method[]
|
||||
*/
|
||||
public function getMethods($filter = -1)
|
||||
{
|
||||
foreach ($res = parent::getMethods($filter) as $key => $val) {
|
||||
$res[$key] = new Method($this->getName(), $val->getName());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return static|null
|
||||
*/
|
||||
public function getParentClass()
|
||||
{
|
||||
return ($ref = parent::getParentClass()) ? new static($ref->getName()) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Property[]
|
||||
*/
|
||||
public function getProperties($filter = -1)
|
||||
{
|
||||
foreach ($res = parent::getProperties($filter) as $key => $val) {
|
||||
$res[$key] = new Property($this->getName(), $val->getName());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Property
|
||||
*/
|
||||
public function getProperty($name)
|
||||
{
|
||||
return new Property($this->getName(), $name);
|
||||
}
|
||||
|
||||
|
||||
/********************* Nette\Annotations support ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* Has class specified annotation?
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return !empty($res[$name]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an annotation value.
|
||||
* @param string
|
||||
* @return IAnnotation
|
||||
*/
|
||||
public function getAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return isset($res[$name]) ? end($res[$name]) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all annotations.
|
||||
* @return IAnnotation[][]
|
||||
*/
|
||||
public function getAnnotations()
|
||||
{
|
||||
return AnnotationsParser::getAll($this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns value of annotation 'description'.
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->getAnnotation('description');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Reports information about a extension.
|
||||
*/
|
||||
class Extension extends \ReflectionExtension
|
||||
{
|
||||
use Nette\SmartObject;
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
|
||||
/********************* Reflection layer ****************d*g**/
|
||||
|
||||
|
||||
public function getClasses()
|
||||
{
|
||||
$res = [];
|
||||
foreach (parent::getClassNames() as $val) {
|
||||
$res[$val] = new ClassType($val);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
public function getFunctions()
|
||||
{
|
||||
foreach ($res = parent::getFunctions() as $key => $val) {
|
||||
$res[$key] = new GlobalFunction($key);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Reports information about a function.
|
||||
* @property-read array $defaultParameters
|
||||
* @property-read bool $closure
|
||||
* @property-read Extension $extension
|
||||
* @property-read Parameter[] $parameters
|
||||
* @property-read bool $disabled
|
||||
* @property-read bool $deprecated
|
||||
* @property-read bool $internal
|
||||
* @property-read bool $userDefined
|
||||
* @property-read string $docComment
|
||||
* @property-read int $endLine
|
||||
* @property-read string $extensionName
|
||||
* @property-read string $fileName
|
||||
* @property-read string $name
|
||||
* @property-read string $namespaceName
|
||||
* @property-read int $numberOfParameters
|
||||
* @property-read int $numberOfRequiredParameters
|
||||
* @property-read string $shortName
|
||||
* @property-read int $startLine
|
||||
* @property-read array $staticVariables
|
||||
*/
|
||||
class GlobalFunction extends \ReflectionFunction
|
||||
{
|
||||
use Nette\SmartObject;
|
||||
|
||||
/** @var string|\Closure */
|
||||
private $value;
|
||||
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
parent::__construct($this->value = $name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function toCallback()
|
||||
{
|
||||
return new Nette\Callback($this->value);
|
||||
}
|
||||
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName() . '()';
|
||||
}
|
||||
|
||||
|
||||
/********************* Reflection layer ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* @return Extension
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
return ($name = $this->getExtensionName()) ? new Extension($name) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Parameter[]
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
foreach ($res = parent::getParameters() as $key => $val) {
|
||||
$res[$key] = new Parameter($this->value, $val->getName());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/********************* Nette\Annotations support ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* Has method specified annotation?
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return !empty($res[$name]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an annotation value.
|
||||
* @param string
|
||||
* @return IAnnotation
|
||||
*/
|
||||
public function getAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return isset($res[$name]) ? end($res[$name]) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all annotations.
|
||||
* @return IAnnotation[][]
|
||||
*/
|
||||
public function getAnnotations()
|
||||
{
|
||||
return AnnotationsParser::getAll($this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns value of annotation 'description'.
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->getAnnotation('description');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
class Helpers
|
||||
{
|
||||
use Nette\StaticClass;
|
||||
|
||||
/**
|
||||
* Returns declaring class or trait.
|
||||
* @return \ReflectionClass
|
||||
* @internal
|
||||
*/
|
||||
public static function getDeclaringClass(\ReflectionProperty $prop)
|
||||
{
|
||||
foreach ($prop->getDeclaringClass()->getTraits() as $trait) {
|
||||
if ($trait->hasProperty($prop->getName())) {
|
||||
return self::getDeclaringClass($trait->getProperty($prop->getName()));
|
||||
}
|
||||
}
|
||||
return $prop->getDeclaringClass();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
|
||||
/**
|
||||
* Code annotation.
|
||||
*/
|
||||
interface IAnnotation
|
||||
{
|
||||
function __construct(array $values);
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Reports information about a method.
|
||||
* @property-read array $defaultParameters
|
||||
* @property-read ClassType $declaringClass
|
||||
* @property-read Method $prototype
|
||||
* @property-read Extension $extension
|
||||
* @property-read Parameter[] $parameters
|
||||
* @property-read IAnnotation[][] $annotations
|
||||
* @property-read string $description
|
||||
* @property-read bool $public
|
||||
* @property-read bool $private
|
||||
* @property-read bool $protected
|
||||
* @property-read bool $abstract
|
||||
* @property-read bool $final
|
||||
* @property-read bool $static
|
||||
* @property-read bool $constructor
|
||||
* @property-read bool $destructor
|
||||
* @property-read int $modifiers
|
||||
* @property-write bool $accessible
|
||||
* @property-read bool $closure
|
||||
* @property-read bool $deprecated
|
||||
* @property-read bool $internal
|
||||
* @property-read bool $userDefined
|
||||
* @property-read string $docComment
|
||||
* @property-read int $endLine
|
||||
* @property-read string $extensionName
|
||||
* @property-read string $fileName
|
||||
* @property-read string $name
|
||||
* @property-read string $namespaceName
|
||||
* @property-read int $numberOfParameters
|
||||
* @property-read int $numberOfRequiredParameters
|
||||
* @property-read string $shortName
|
||||
* @property-read int $startLine
|
||||
* @property-read array $staticVariables
|
||||
*/
|
||||
class Method extends \ReflectionMethod
|
||||
{
|
||||
use Nette\SmartObject;
|
||||
|
||||
/**
|
||||
* @param string|object
|
||||
* @param string
|
||||
* @return static
|
||||
*/
|
||||
public static function from($class, $method)
|
||||
{
|
||||
return new static(is_object($class) ? get_class($class) : $class, $method);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function toCallback()
|
||||
{
|
||||
return new Nette\Callback(parent::getDeclaringClass()->getName(), $this->getName());
|
||||
}
|
||||
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return parent::getDeclaringClass()->getName() . '::' . $this->getName() . '()';
|
||||
}
|
||||
|
||||
|
||||
/********************* Reflection layer ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* @return ClassType
|
||||
*/
|
||||
public function getDeclaringClass()
|
||||
{
|
||||
return new ClassType(parent::getDeclaringClass()->getName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function getPrototype()
|
||||
{
|
||||
$prototype = parent::getPrototype();
|
||||
return new static($prototype->getDeclaringClass()->getName(), $prototype->getName());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Extension
|
||||
*/
|
||||
public function getExtension()
|
||||
{
|
||||
return ($name = $this->getExtensionName()) ? new Extension($name) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Parameter[]
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
$me = [parent::getDeclaringClass()->getName(), $this->getName()];
|
||||
foreach ($res = parent::getParameters() as $key => $val) {
|
||||
$res[$key] = new Parameter($me, $val->getName());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/********************* Nette\Annotations support ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* Has method specified annotation?
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return !empty($res[$name]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an annotation value.
|
||||
* @param string
|
||||
* @return IAnnotation
|
||||
*/
|
||||
public function getAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return isset($res[$name]) ? end($res[$name]) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all annotations.
|
||||
* @return IAnnotation[][]
|
||||
*/
|
||||
public function getAnnotations()
|
||||
{
|
||||
return AnnotationsParser::getAll($this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns value of annotation 'description'.
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->getAnnotation('description');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Reports information about a method's parameter.
|
||||
* @property-read ClassType $class
|
||||
* @property-read string $className
|
||||
* @property-read ClassType $declaringClass
|
||||
* @property-read Method $declaringFunction
|
||||
* @property-read string $name
|
||||
* @property-read bool $passedByReference
|
||||
* @property-read bool $array
|
||||
* @property-read int $position
|
||||
* @property-read bool $optional
|
||||
* @property-read bool $defaultValueAvailable
|
||||
* @property-read mixed $defaultValue
|
||||
*/
|
||||
class Parameter extends \ReflectionParameter
|
||||
{
|
||||
use Nette\SmartObject;
|
||||
|
||||
/** @var mixed */
|
||||
private $function;
|
||||
|
||||
|
||||
public function __construct($function, $parameter)
|
||||
{
|
||||
parent::__construct($this->function = $function, $parameter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ClassType
|
||||
*/
|
||||
public function getClass()
|
||||
{
|
||||
return ($ref = parent::getClass()) ? new ClassType($ref->getName()) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClassName()
|
||||
{
|
||||
try {
|
||||
return ($ref = parent::getClass()) ? $ref->getName() : null;
|
||||
} catch (\ReflectionException $e) {
|
||||
if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) {
|
||||
return $m[1];
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return ClassType
|
||||
*/
|
||||
public function getDeclaringClass()
|
||||
{
|
||||
return ($ref = parent::getDeclaringClass()) ? new ClassType($ref->getName()) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Method|GlobalFunction
|
||||
*/
|
||||
public function getDeclaringFunction()
|
||||
{
|
||||
return is_array($this->function)
|
||||
? new Method($this->function[0], $this->function[1])
|
||||
: new GlobalFunction($this->function);
|
||||
}
|
||||
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return '$' . parent::getName() . ' in ' . $this->getDeclaringFunction();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Nette Framework (https://nette.org)
|
||||
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
|
||||
*/
|
||||
|
||||
namespace Nette\Reflection;
|
||||
|
||||
use Nette;
|
||||
|
||||
|
||||
/**
|
||||
* Reports information about a classes variable.
|
||||
* @property-read ClassType $declaringClass
|
||||
* @property-read IAnnotation[][] $annotations
|
||||
* @property-read string $description
|
||||
* @property-read string $name
|
||||
* @property mixed $value
|
||||
* @property-read bool $public
|
||||
* @property-read bool $private
|
||||
* @property-read bool $protected
|
||||
* @property-read bool $static
|
||||
* @property-read bool $default
|
||||
* @property-read int $modifiers
|
||||
* @property-read string $docComment
|
||||
* @property-write bool $accessible
|
||||
*/
|
||||
class Property extends \ReflectionProperty
|
||||
{
|
||||
use Nette\SmartObject;
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return parent::getDeclaringClass()->getName() . '::$' . $this->getName();
|
||||
}
|
||||
|
||||
|
||||
/********************* Reflection layer ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* @return ClassType
|
||||
*/
|
||||
public function getDeclaringClass()
|
||||
{
|
||||
return new ClassType(parent::getDeclaringClass()->getName());
|
||||
}
|
||||
|
||||
|
||||
/********************* Nette\Annotations support ****************d*g**/
|
||||
|
||||
|
||||
/**
|
||||
* Has property specified annotation?
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return !empty($res[$name]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an annotation value.
|
||||
* @param string
|
||||
* @return IAnnotation
|
||||
*/
|
||||
public function getAnnotation($name)
|
||||
{
|
||||
$res = AnnotationsParser::getAll($this);
|
||||
return isset($res[$name]) ? end($res[$name]) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all annotations.
|
||||
* @return IAnnotation[][]
|
||||
*/
|
||||
public function getAnnotations()
|
||||
{
|
||||
return AnnotationsParser::getAll($this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns value of annotation 'description'.
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->getAnnotation('description');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user