gbecchio / addendum

Automatically exported from code.google.com/p/addendum
GNU Lesser General Public License v2.1
0 stars 0 forks source link

Annotations do not support inheritance #22

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
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 kens...@gmail.com on 2 Sep 2010 at 3:42

GoogleCodeExporter commented 9 years ago
Hi, could you please add a real world use case why do you need something like 
this? Just curious.

Original comment by jan.suc...@gmail.com on 2 Sep 2010 at 5:49

GoogleCodeExporter commented 9 years ago
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 kens...@gmail.com on 2 Sep 2010 at 2:46

GoogleCodeExporter commented 9 years ago
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 jan.suc...@gmail.com on 2 Sep 2010 at 3:01

GoogleCodeExporter commented 9 years ago
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 kens...@gmail.com on 2 Sep 2010 at 6:33

GoogleCodeExporter commented 9 years ago
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? (johno@jsmf.net) I am really 
curious.

Original comment by jan.suc...@gmail.com on 6 Sep 2010 at 6:10

GoogleCodeExporter commented 9 years ago
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 kens...@gmail.com on 6 Sep 2010 at 2:34