Register namespace prefix(es) for concrete annotations?
For project organization reasons I need my concrete annotation classes to reside in a deeply nested namespace, but I don't want to type the whole namespace path every time I use the annotation. It would be very welcome if I could register namespace prefix(es) for concrete annotation classes.
Doctrine annotations does that, but it comes to the expense of parsing the file containing the dockblock looking for use statements.
An alternative approach could be to set the prefix on the annotation reader:
$reader->getParser()->registerFallbackNamespace('\My\CustomNamespace');
/**
* @MyAnnotation -> {'foo': ['bar']}
*/
class SomeClass {}
$annotations = $reader->getClassAnnotations(SomeClass::class);
assert($annotations['\MyAnnotation'] === null);
assert($annotations['\My\CustomNamespace\MyAnnotation'] instanceof Someclass);
Unfortunately that alternative is not good as it could create interoperability issues. I guess parsing the file is the only way to go, but it should be activated optionally:
use My\CustomNamespace\MyAnnotation;
$reader->getParser()->resolveUseStatementsFromSource(true);
/**
* @MyAnnotation -> {'foo': ['bar']}
*/
class SomeClass {}
$annotations = $reader->getClassAnnotations(SomeClass::class);
assert($annotations['\MyAnnotation'] === null);
assert($annotations['\My\CustomNamespace\MyAnnotation'] instanceof Someclass);
I managed to achieve what I need by subclassing Parser and ConcreteType. As for the general solution, what specific interoperability issues do you foresee with registerFallbackNamespace() approach?
Consider MyPackage\Validation\Email and OtherPackage\Validation\Email implementing a common Yada\ValidatorInterface, you won't be able to resolve both concrete annotations if needed.
If you have two different classes with same name you definitely have to use them appropriately in the code (and/or docblock in this case)
Yesterday evening had a bit of a fiddle with this simple library to adapt registered namespace and worked out well in a lightweight framework currently trying to upgrade. Probably needs a bit of clean-up, fresh eyes as it was late in the night. Going to fork now and see what I have done
Can apply multiple registered namespaces too, but again, if you have same names for the class - that is a local project scope matter to deal with