addendum
addendum copied to clipboard
Annotations do not support inheritance
What steps will reproduce the problem?
/** Target('class') */
class AAA extends Annotation { }
/** Target('property') */
class BBB extends Annotation { }
/** @AAA('no') */
class x {
/** @BBB('no') */
public $my_var;
}
class y extends x { }
$obj = new y();
$reflection = new ReflectionAnnotatedClass($obj);
echo "Are Annotations inherited >> ".((int)$reflection->hasAnnotation('AAA'));
What is the expected output? What do you see instead?
Expected:
Are Annotations inherited >> 1
Instead:
Are Annotations inherited >> 0
What version of the product are you using? On what operating system?
svn HEAD on Debian
Please provide any additional information below.
I would be willing to write it (it seems extremely simple to implement) if
given SVN access.
I think you should be able to annotate Annotations with another special one
like target like this:
/**
@Target('class')
@Inheritable(true)
*/
class AAA extends Annotation { }
You could then toggle the inheritance of the attribute per method, property, or
class. It would be simply some updates to the internal.
Original issue reported on code.google.com by [email protected] on 2 Sep 2010 at 3:42
Hi, could you please add a real world use case why do you need something like
this? Just curious.
Original comment by [email protected] on 2 Sep 2010 at 5:49
When you have a large set of objects that inherit from a common class and don't
want to recreate the Annotations on each inherited object. Or if you have a
hierarchy of objects and want to set it on the tree.
In C#, with attributes, you can toggle the inheritance of the attribute.
Original comment by [email protected] on 2 Sep 2010 at 2:46
Ok, but could you please be more specific? I am yet to be convinced about a
real world usage of inheritable annotations.
It's not a big problem, but I would love to see what you are doing in real
world.
Original comment by [email protected] on 2 Sep 2010 at 3:01
I can't (unfortunately) put in specific code at this time, but it is something
like this:
/** @Default('value') */
class Element {
final public function getDefault() {
// use annotated default value if there is no default value set
// (ie, via a setDefault or via the constructor or some such)
$reflection = new ReflectionAnnotatedClass($this);
if (!isset($this->params['default']) && $reflection->hasAnnotation('DefaultValue')) {
return $reflection->getAnnotation('DefaultValue')->value;
}
return $this->params['default'];
}
}
class ElementName extends Element { }
/** @DefaultValue('new default value') */
class SomeOtherElement extends ElementName { }
Note that ElementName doesn't get a DefaultValue annotation -- it should
inherit that from the parent class (if that annotation is inheritable).
Basically I don't want to redefine the DefaultValue (and many other things that
I'm defining with Annotations in a class heirarchy). So something that is
understood by a final function in a parent class. I'm using this in a
combination of a Template Method design pattern and a Strategy pattern for
encapsulating things such as Regular Expression validators etc.
(please excuse the example above. I wrote it extremely quickly).
Original comment by [email protected] on 2 Sep 2010 at 6:33
Hmm, this seems like not only inheritance, but also as a kind of "overloading"
behavior.
What bothers me, now is what will happen if you have multiple valued annotation
a you try to overload/inherit only some of the attributes. What is the desired
behavior?
Could you send your specific code via email? ([email protected]) I am really
curious.
Original comment by [email protected] on 6 Sep 2010 at 6:10
Overloading would work the same as regular object oriented overloading. Say you
had Class A, B, and C, where B inherits from A, and C inherits from B, then
Annotation overloading would work the same. For instance, if class B overloads
Annotations from class A, then class C would inherit the annotations from class
B.
I will try to send you some specific examples, but its just mainly for setting
default values in an element hierarchy. This is useful in producing/consuming
very complex XML documents that represent such things.
Also, since I seem to have you on the line -- what would you think of adding
getTypeHint() for parameters to functions/methods? Eventually PHP will include
it in the language (its in trunk/ it's just not in 5.3 or 5.2 -- see
http://ilia.ws/archives/207-Type-Hinting-Conclusion.html). As stop-gap measure,
it would sure make things a bit easier for me ;) Heh.
Original comment by [email protected] on 6 Sep 2010 at 2:34