Vylepšení anotací
- paranoiq
- Člen | 392
mám návrh na dvě vylepšení anotací. Nette\Annotations neumí typ NULL a neumí klasické dokumentační anotace bez závorek. pro anotace typu „@anotace text“ vrací místo textu jen TRUE. což je škoda. jednak nejdou číst dokumentační anotace a pak zapisování skalárů bez závorek je pohodlnější
patch:
Index: Annotations.php
===================================================================
--- Annotations.php (revision 484)
+++ Annotations.php (working copy)
@@ -109,11 +109,11 @@
return $cache;
}
- preg_match_all('#@([a-zA-Z0-9_]+)(?:\(((?>[^\'")]+|\'[^\']*\'|"[^"]*")*)\))?#', $r->getDocComment(), $matches, PREG_SET_ORDER);
+ preg_match_all('#@([a-zA-Z0-9_]+)(?:\(((?>[^\'")]+|\'[^\']*\'|"[^"]*")*)\))?(?:[\t ]+(.+[^\s]))?#', $r->getDocComment(), $matches, PREG_SET_ORDER);
$cache = array();
foreach ($matches as $match)
{
- if (isset($match[2])) {
+ if (isset($match[2]) && $match[2] != '') {
preg_match_all('#[,\s](?>([a-zA-Z0-9_]+)\s*=\s*)?([^\'",\s][^,]*|\'[^\']*\'|"[^"]*")#', ',' . $match[2], $matches, PREG_SET_ORDER);
$items = array();
$key = '';
@@ -129,6 +129,9 @@
} elseif (strcasecmp($val, 'false') === 0) {
$val = FALSE;
+ } elseif (strcasecmp($val, 'null') === 0) {
+ $val = NULL;
+
} elseif (is_numeric($val)) {
$val = 1 * $val;
}
@@ -143,6 +146,22 @@
$items = count($items) < 2 && $key === '' ? $val : new /*\*/ArrayObject($items, /*\*/ArrayObject::ARRAY_AS_PROPS);
+ } elseif (isset($matches[3])) {
+ $val = $match[3];
+ if (strcasecmp($val, 'true') === 0) {
+ $val = TRUE;
+
+ } elseif (strcasecmp($val, 'false') === 0) {
+ $val = FALSE;
+
+ } elseif (strcasecmp($val, 'null') === 0) {
+ $val = NULL;
+
+ } elseif (is_numeric($val)) {
+ $val = 1 * $val;
+ }
+ $items = $val;
+
} else {
$items = TRUE;
}
„@anotace null“ vrátí typ NULL, stejně jako varianta v závorce.
„@anotace ‚bla bla‘“ vrátí „‚bla bla‘“. uvozovky se neořezávají. je-li přítomna závorka i text, text se ignoruje: „@anotace(klic='hodnota') bla bla“ tedy vrátí to samé co vrací nyní
Davide, prosím, přidej to tam :]
- paranoiq
- Člen | 392
k tomu bugu + přeuspořádaná keš a rozšíření o anotace u funkcí
static protected function & init(/*\*/Reflector $r) {
if ($r instanceof /*\*/ReflectionClass) {
$class = $r->getName();
$name = '';
} elseif ($r instanceof /*\*/ReflectionProperty) {
$class = $r->getDeclaringClass()->getName();
$name = '$' . $r->getName();
} elseif ($r instanceof /*\*/ReflectionMethod) {
$class = $r->getDeclaringClass()->getName();
$name = $r->getName();
} elseif ($r instanceof /*\*/ReflectionFunction) {
$class = '';
$name = $r->getName();
} else {
throw new InvalidArgumentException('Cannot get annotations from an ' . get_class($r) . '!');
}
$cache = & self::$cache[$class][$name];
if ($cache !== NULL) {
return $cache;
}
...
tu dědičnost zvažuju. nejsem si jistý, zda to bude tak užitečné jak jsem si myslel…
Editoval paranoiq (18. 8. 2009 10:47)
- paranoiq
- Člen | 392
Davide, díky za opravu a díky za NULL
jak to vidíš s tím parsováním normálních (dokumentačních)
anotací?
bylo by to velmi užitečné například pro znovupoužití anotace @var
(deserializace atp.)
(viděl jsem to i jinde. je dost zvláštní věc, že hned několik parserů anotací ignoruje zažitou syntaxi anotací, která se používá pro PHPDoc)
- Patrik Votoček
- Člen | 2221
Nechtěl by někdo sepsat do Docky jak to funguje? Protože
bych to rád využil ale absolutně to nechápu. A myslím že nejsem
jediný.
Díky.
- redhead
- Člen | 1313
Je nějaký způsob jak zadávat pole??
zkoušel jsem:
/**
* @abc ( xyz = (ijk, lmn) )
* nebo
* @abc ( xyz = array(ijk, lmn) )
*/
ale nejde, předpokládám, že to není ani implementováno. Ale byla by to zajímavá feature (a pro mě i prospěšná)! Šlo by to implementovat?
Editoval redhead (7. 2. 2010 22:33)
- redhead
- Člen | 1313
někdy se to může hodit, příklad – mám zautomatizovanou podporu cache pro nějaké metody v modelu a podle anotace ‚cache‘ ji chci kešovat:
/** @cache(expire = 604800, tags = (bli, ble, blu)) */
public function necoTahamZDb()
{
//...
}
a podle toho by se nastavovala cache, ty tagy by byli v poli, aby se s nima dobře pracovalo. Samozřejmě to můžu dát do jiné anotace (třeba cache-tags), ale už to není tak pohodlné..
- Petr Motejlek
- Člen | 293
redhead napsal(a):
někdy se to může hodit, příklad…
To bych taky ocenil, ale aby to bylo možné prohat třeba fcí eval(), bylo by lepší tam mít napsáno tags = array(ble, ble, ble) ;)
- Patrik Votoček
- Člen | 2221
Petr Motejlek napsal(a):
…ale aby to bylo možné prohat třeba fcí eval()…
Auuuuuu (právě jsem se moc nechápavě praštil do hlavy)
- Petr Motejlek
- Člen | 293
Je to můj názor, ale zdá se mi, že je vhodnější, abych i v anotacích musel normálně dodržovat zápisy, které používá daný jazyk. (ble, ble, ble) prostě v PHP nic neznamená a je syntakticky špatně. Úplně nejvíc by se mi líbilo, aby se to zapisovalo jako array(‚ble‘, ‚ble‘, ‚ble‘). Už proto, že například 2 je něco jiného než ‚2‘. Ten eval() jsem naznačil právě kvůli tomu, že si myslím, že by to mělo být syntakticky správně.
Díky té nové podpoře anotací by měla stejně každá anotace způsobit vytvoření instance nějaké třídy, které se předá, co v té anotaci je. Jestli se na ni použije nějakej šílenej regulár, nebo se z toho udělá eval(), a budu moct použít i tu konstrukci typu 24 * 60 * 60, proč ne? Vždyť se to stejně cachuje…
Editoval Petr Motejlek (15. 2. 2010 22:14)
- Petr Motejlek
- Člen | 293
vrtak-cz napsal(a):
Petr Motejlek napsal(a):
…ale aby to bylo možné prohat třeba fcí eval()…
Auuuuuu (právě jsem se moc nechápavě praštil do hlavy)
Tak to jsem úplně nepochopil…
- Petr Motejlek
- Člen | 293
Já ten eval() jako takovej neprosazuju, určitě to není to nejlepší řešení. Mě osobně se strašně líbí, jak jsou řešené anotace například v Javě, a rád bych se podobnýho principu držel i v Nette. Je jasný, že je někde chyba v návrhu, když budu chtít v rámci anotace používat neprimitivní datový typy a funkce. Nicméně by se mi líbilo, abych na první pohled poznal, z titulu, že znám syntax PHP, co daná anotace představuje.