rfc:simple-annotations

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Last revisionBoth sides next revision
rfc:simple-annotations [2016/05/13 09:35] – created mindplayrfc:simple-annotations [2016/06/27 17:45] – remove provision about reserved annotations mindplay
Line 1: Line 1:
 ====== PHP RFC: Simple Annotations ====== ====== PHP RFC: Simple Annotations ======
  
-  * Version: 0.1+  * Version: 0.3
   * Date: 2016-05-13   * Date: 2016-05-13
   * Author: Rasmus Schultz, rasmus@mindplay.dk   * Author: Rasmus Schultz, rasmus@mindplay.dk
Line 9: Line 9:
 ===== Introduction ===== ===== Introduction =====
  
-This RFC proposes the introduction of simple value annotations - arbitrary meta-data values applicable to classes and class members, obtainable via the reflection API.+This RFC proposes the introduction of simple value annotations - arbitrary values attached to classes and class members as meta-data, obtainable via reflection.
  
 As an alternative proposal to [[https://wiki.php.net/rfc/attributes|attributes]], this proposal aims to fully leverage existing language features, in order to provide more flexibility, lessen the learning curve, and expose meta-data in a manner that is more immediately useful, without having to build any run-time facilities. As an alternative proposal to [[https://wiki.php.net/rfc/attributes|attributes]], this proposal aims to fully leverage existing language features, in order to provide more flexibility, lessen the learning curve, and expose meta-data in a manner that is more immediately useful, without having to build any run-time facilities.
  
-Compared with annotation systems such as [[https://github.com/doctrine/annotations|Doctrine Annotations]], this proposal does not attempt to define or enforce any domain rules - it does not define inheritance semantics, rules about applicable source-code elements, or any other rules; these can be defined and implemented by userland packages.+Compared with annotation systems such as [[https://github.com/doctrine/annotations|Doctrine Annotations]], this proposal does not attempt to define or enforce any domain rules - it does not define inheritance semantics, rules about applicable source-code elements, cardinality, or any other rules; these can be defined and implemented by userland packages.
  
 ===== Proposal ===== ===== Proposal =====
  
-The proposed syntax of a single annotation is extremely simple:+The proposed syntax of a single annotation is very simple:
  
 <code> <code>
Line 29: Line 29:
   * ''class'', ''trait'' and ''interface'' declarations   * ''class'', ''trait'' and ''interface'' declarations
   * ''function'' and property declarations in classes/traits/interfaces   * ''function'' and property declarations in classes/traits/interfaces
-  * function and method argument declarations +  * anonymous ''function'' declarations 
-  * anonymous ''function'' and ''class'' declarations (and their members)+  * anonymous ''class'' declarations (and their members) 
 +  * argument declarations of functions, methods and closures
  
-For example:+Annotations are internally collected, for each annotated class or member, in a list which can be obtained via reflection. 
 + 
 +The following trivial example annotates a class with a string and an array of numbers:
  
 <code php> <code php>
-class Table +<< "Hello World" >> 
-{+<< [1, 2, 3] >> 
 +class Hello 
 +{
 +</code>
  
 +The following example annotates an entity with a ''TableName'' instance, which might be consumed by a database abstraction:
 +
 +<code php>
 +class TableName
 +{
 +    public $name;
 +    
     public function __construct($name) {     public function __construct($name) {
         $this->name = $name;         $this->name = $name;
     }     }
 } }
 +
 +<< new TableName("users") >>
 +class User
 +{
 +    // ...
 +}
 +
 +$reflection = new ReflectionClass(User::class);
 +
 +var_dump($reflection->getAnnotations());
 </code> </code>
  
-Annotations are internally collectedfor each annotated class or memberin a list which can be obtained via reflection.+Example output: 
 + 
 +<code> 
 +array(1) { 
 +  [0]=> 
 +  object(TableName)#1 (1) { 
 +    ["name"]=> 
 +    string(5) "users" 
 +  } 
 +
 +</code> 
 + 
 +Annotation expressions are not evaluated until reflection is invoked, and are evaluated only once and internally memoized upon the first call to ''getAnnotations()''
 + 
 +==== Annotations are Context-free ==== 
 + 
 +By designannotations expressions are evaluated individually in an empty scope - which means there is no access to variables in the parent class, file, local or global scopee.g. no ''$this'', ''self'' or ''static''
 + 
 +Annotations work consistently regardless of which source element they are applied to, and may be evaluated without first creating an object instance. 
 + 
 +Annotations that do require context should explicitly ask for that context - for example, you could use an anonymous function, a ''callable'', or an anonymous class, to provide context via dependency injection. 
 + 
 +==== Reflection API ==== 
 + 
 +The following classes will have an added ''getAnnotations()'' method: 
 + 
 + * ''ClassReflection'' 
 + * ''ReflectionFunctionAbstract'' (''ReflectionFunction'' and ''ReflectionMethod''
 + * ''ReflectionProperty'' 
 + * ''ReflectionParameter'' 
 + 
 +The ''getAnnotations()'' method has the following signature: 
 + 
 +    public function getAnnotations($filter = null) : array 
 + 
 +The optional ''$filter'' argument, if given, filters the returned list of annotations as follows: 
 + 
 +   * If one of ''string'', ''int'', ''float'', ''bool'' are given, filters annotations using ''is_int()'', ''is_string()'', etc. 
 +   * If a fully-qualified class-name is given, filters annotations using ''instanceof'' 
 + 
 +If ''null'' is given (default) all annotations are returned. 
 + 
 +These methods do not take into account inheritance - annotations belong to the actual *declaration*, not to an abstract *member*, and as such, traversing parent classes, interfaces, etc. is up to the consumer.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 76: Line 141:
 Annotations are a new feature - it does not affect any existing functionality. Annotations are a new feature - it does not affect any existing functionality.
  
-===== Future Scope =====+===== Out of Scope =====
  
-TODO file-level annotations? others?+It has been suggested that this RFC should reserve certain names for compiler directives, such as (for instance) the memoization-directive [[https://docs.hhvm.com/hack/attributes/special|supported by Hack]]. This proposal does not reserve any such names, because (as others pointed out during that discussion) these are not meta-data, but rather directives for the compiler, and such features ought to be supported directly by keywords or syntax rather than by magical meta-data.
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
Line 102: Line 167:
  
 None. None.
- 
rfc/simple-annotations.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1