Changeset 433

Show
Ignore:
Timestamp:
03/28/07 23:46:54 (1 year ago)
Author:
mikey
Message:

overhauled annotation parser:
moved to net.stubbles.reflection.annotations.parser
added checks for annotation names, annotation types and annotation param names
added more doc blocks
removed a lot of tabs

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/docroot/annotationParser.php

    r424 r433  
    33require_once '../src/main/php/net/stubbles/stubClassLoader.php'; 
    44stubClassLoader::load('net.stubbles.reflection.reflection', 
    5                       'net.stubbles.reflection.parser.stubAnnotationParser'); 
    6  
     5                      'net.stubbles.reflection.annotations.parser.stubAnnotationParser' 
     6); 
    77/** 
    88 * This is some text.... 
     
    1717 * @SingleValue(42) 
    1818 * @SingleStringValue('This is a string with chars like = or ,') 
    19  * @WithEscaped(foo='This string containing \' and \\, which is possible using escaping...') 
     19 * @WithEscaped(foo='This string contains \' and \\, which is possible using escaping...') 
    2020 * @Multiline(one=1, 
    2121 *            two=2) 
     
    2626 */ 
    2727class MyTestClass { 
    28      
     28    // intentionally empty 
    2929} 
    3030 
    31 $clazz = new ReflectionClass('MyTestClass'); 
    32 $docBlock = $clazz->getDocComment(); 
    33  
    34 $parser = new stubAnnotationParser(); 
     31$clazz       = new ReflectionClass('MyTestClass'); 
     32$docBlock    = $clazz->getDocComment(); 
     33$parser      = new stubAnnotationParser(); 
    3534$annotations = $parser->parse($docBlock); 
    36  
     35echo '<pre>'; 
    3736print_r($annotations); 
    3837 
  • trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParser.php

    r424 r433  
    11<?php 
    22/** 
    3  * Parser to parse Java-Style annotations 
     3 * Parser to parse Java-Style annotations. 
    44 * 
    55 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    67 * @package     stubbles 
    7  * @subpackage  reflection 
     8 * @subpackage  reflection_annotations_parser 
    89 */ 
    9 stubClassLoader::load('net.stubbles.reflection.parser.stubAnnotationParserState', 
    10                       'net.stubbles.reflection.parser.stubAnnotationParserAbstractState', 
    11                       'net.stubbles.reflection.parser.stubAnnotationParserDefaultState', 
    12                       'net.stubbles.reflection.parser.stubAnnotationParserAnnotationState', 
    13                       'net.stubbles.reflection.parser.stubAnnotationParserAnnotationNameState', 
    14                       'net.stubbles.reflection.parser.stubAnnotationParserAnnotationTypeState', 
    15                       'net.stubbles.reflection.parser.stubAnnotationParserAnnotationParamsState', 
    16                       'net.stubbles.reflection.parser.stubAnnotationParserAnnotationParamNameState', 
    17                       'net.stubbles.reflection.parser.stubAnnotationParserAnnotationParamValueState'); 
    18  
     10stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserState', 
     11                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 
     12                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserDefaultState', 
     13                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserAnnotationState', 
     14                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserAnnotationNameState', 
     15                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserAnnotationTypeState', 
     16                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserAnnotationParamsState', 
     17                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserAnnotationParamNameState', 
     18                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserAnnotationParamValueState' 
     19); 
    1920/** 
    20  * Parser to parse Java-Style annotations 
     21 * Parser to parse Java-Style annotations. 
    2122 * 
    22  * @author      Stephan Schmidt <schst@stubbles.net> 
    2323 * @package     stubbles 
    24  * @subpackage  reflection 
    25  * @todo       Improve error handling 
    26  * @todo       Write unit tests 
     24 * @subpackage  reflection_annotations_parser 
     25 * @todo        improve error handling 
     26 * @todo        write unit tests 
    2727 */ 
    2828class stubAnnotationParser 
    2929{ 
    30     /** 
    31      * Parser is inside the standard docblock 
    32      */ 
    33     const STATE_DEFAULT = 0; 
    34     /** 
    35      * Parser is inside an annotation 
    36      */ 
    37     const STATE_ANNOTATION = 1; 
    38     /** 
    39      * Parser is inside an annotation name 
    40      */ 
    41     const STATE_ANNOTATION_NAME = 2; 
    42     /** 
    43      * Parser is inside an annotation type 
    44      */ 
    45     const STATE_ANNOTATION_TYPE = 3; 
    46     /** 
    47      * Parser is inside the annotation params 
    48      */ 
    49     const STATE_PARAMS = 4; 
    50     /** 
    51      * Parser is inside an annotation param nane 
    52      */ 
    53     const STATE_PARAM_NAME = 5; 
    54     /** 
    55      * Parser is inside an annotation param value 
    56      */ 
    57     const STATE_PARAM_VALUE = 6; 
    58  
    59     /** 
    60      * Possible states 
    61      * 
    62      * @var array 
    63      */ 
    64     private $states = array(); 
    65      
    66     /** 
    67      * The current state 
    68      * 
    69      * @var stubAnnotationParserState 
    70      */ 
    71     private $currentState = null; 
    72      
    73     /** 
    74      * The name of the current annotation 
    75      * 
    76      * @var string 
    77      */ 
    78     private $currentAnnotation = null; 
    79      
    80     /** 
    81      * The name of the current annotation parameter 
    82      * 
    83      * @var string 
    84      */ 
    85     private $currentParam = null; 
    86  
    87     /** 
    88      * All parsed annotations 
    89      * 
    90      * @var array 
    91      */ 
    92     private $annotations = array(); 
    93      
    94     /** 
    95      * Create a new parser and setup all states 
    96      * 
    97      */ 
    98     public function __construct() { 
    99         $this->states[self::STATE_DEFAULT] = new stubAnnotationParserDefaultState($this); 
    100         $this->states[self::STATE_ANNOTATION] = new stubAnnotationParserAnnotationState($this); 
    101         $this->states[self::STATE_ANNOTATION_NAME] = new stubAnnotationParserAnnotationNameState($this); 
    102         $this->states[self::STATE_ANNOTATION_TYPE] = new stubAnnotationParserAnnotationTypeState($this); 
    103         $this->states[self::STATE_PARAMS] = new stubAnnotationParserParamsState($this); 
    104         $this->states[self::STATE_PARAM_NAME] = new stubAnnotationParserParamNameState($this); 
    105         $this->states[self::STATE_PARAM_VALUE] = new stubAnnotationParserParamValueState($this); 
    106     } 
    107  
    108     /** 
    109      * Change the current state 
    110      * 
    111      * @param int $state 
    112      * @param string $token The token that should be processed by the state 
    113      */ 
    114     public function changeState($state, $token = null) { 
    115         if (!isset($this->states[$state])) { 
    116             throw new Exception('Unknown state ' . $state); 
    117         } 
    118         $this->currentState = $this->states[$state]; 
    119         $this->currentState->selected(); 
    120         if ($token != null) { 
    121             $this->currentState->process($token); 
    122         } 
    123     } 
    124  
    125     /** 
    126      * Parse a docblock 
    127      * 
    128      * @param string $docBlock 
    129      */ 
    130     public function parse($docBlock) { 
    131         $this->annotations = null; 
    132         $this->changeState(self::STATE_DEFAULT); 
    133         $len = strlen($docBlock); 
    134         for ($i = 0; $i < $len; $i++) { 
    135 //          echo "Processing " . $docBlock{$i} . "\n"; 
    136             $this->currentState->process($docBlock{$i}); 
    137         } 
    138         return $this->annotations; 
    139     } 
    140  
    141     /** 
    142      * Register a new annotation 
    143      * 
    144      * @param string $name 
    145      */ 
    146     public function registerAnnotation($name) { 
    147         $this->annotations[$name] = array('type' => $name, 'params' => array()); 
    148         $this->currentAnnotation = $name; 
    149     } 
    150  
    151     /** 
    152      * Register a new annotation param 
    153      * 
    154      * @param string $name 
    155      */ 
    156     public function registerAnnotationParam($name) { 
    157         $this->currentParam = trim($name); 
    158     } 
    159      
    160     /** 
    161      * Register single annotation param 
    162      * 
    163      * @param string $value 
    164      */ 
    165     public function registerSingleAnnotationParam($value, $asString = false) { 
    166         $value = $this->convertAnnotationValue($value, $asString); 
    167         if (count($this->annotations[$this->currentAnnotation]['params'])) { 
    168             throw new ReflectionException('Error parsing annotation ' . $this->currentAnnotation); 
    169         } 
    170         $this->annotations[$this->currentAnnotation]['params']['value'] = $value; 
    171     } 
    172      
    173     /** 
    174      * Set the annoation param value for the current annotation 
    175      * 
    176      * @param mixed $value 
    177      */ 
    178     public function setAnnotationParamValue($value, $asString = false) { 
    179         $this->annotations[$this->currentAnnotation]['params'][$this->currentParam] = $this->convertAnnotationValue($value, $asString); 
    180     } 
    181  
    182     /** 
    183      * Set the type of the current annotation 
    184      * 
    185      * @param string $type 
    186      */ 
    187     public function setAnnotationType($type) { 
    188         $this->annotations[$this->currentAnnotation]['type'] = $type; 
    189     } 
    190  
    191     /** 
    192      * Convert an annotation value 
    193      * 
    194      * @param string $value 
    195      * @param boolean $asString 
    196      * @return mixed 
    197      * @todo Improve type detection and error handling 
    198      */ 
    199     protected function convertAnnotationValue($value, $asString) { 
    200         if ($asString) { 
    201             return (string)$value; 
    202         } 
    203         if ($value === 'true') { 
    204             return true; 
    205         } 
    206         if ($value === 'false') { 
    207             return false; 
    208         } 
    209         if (preg_match('/^[+-]?[0-9]+$/', $value)) {             
    210             return (integer)$value; 
    211         } 
    212         $matches = array(); 
    213         if (preg_match('/^([a-zA-Z\.]+)\.class/', $value, $matches)) { 
    214             return new stubReflectionClass($matches[1]); 
    215         } 
    216         throw new ReflectionException('Could not determine type of value ' . $value); 
    217     } 
     30    /** 
     31     * parser is inside the standard docblock 
     32     */ 
     33    const STATE_DEFAULT         = 0; 
     34    /** 
     35     * parser is inside an annotation 
     36     */ 
     37    const STATE_ANNOTATION      = 1; 
     38    /** 
     39     * parser is inside an annotation name 
     40     */ 
     41    const STATE_ANNOTATION_NAME = 2; 
     42    /** 
     43     * parser is inside an annotation type 
     44     */ 
     45    const STATE_ANNOTATION_TYPE = 3; 
     46    /** 
     47     * parser is inside the annotation params 
     48     */ 
     49    const STATE_PARAMS          = 4; 
     50    /** 
     51     * parser is inside an annotation param nane 
     52     */ 
     53    const STATE_PARAM_NAME      = 5; 
     54    /** 
     55     * parser is inside an annotation param value 
     56     */ 
     57    const STATE_PARAM_VALUE     = 6; 
     58    /** 
     59     * possible states 
     60     * 
     61     * @var  array 
     62     */ 
     63    private $states             = array(); 
     64    /** 
     65     * the current state 
     66     * 
     67     * @var  stubAnnotationParserState 
     68     */ 
     69    private $currentState       = null; 
     70    /** 
     71     * the name of the current annotation 
     72     * 
     73     * @var  string 
     74     */ 
     75    private $currentAnnotation  = null; 
     76    /** 
     77     * the name of the current annotation parameter 
     78     * 
     79     * @var  string 
     80     */ 
     81    private $currentParam       = null; 
     82    /** 
     83     * all parsed annotations 
     84     * 
     85     * @var  array 
     86     */ 
     87    private $annotations        = array(); 
     88 
     89    /** 
     90     * constructor 
     91     */ 
     92    public function __construct() 
     93    { 
     94        $this->states[self::STATE_DEFAULT]         = new stubAnnotationParserDefaultState($this); 
     95        $this->states[self::STATE_ANNOTATION]      = new stubAnnotationParserAnnotationState($this); 
     96        $this->states[self::STATE_ANNOTATION_NAME] = new stubAnnotationParserAnnotationNameState($this); 
     97        $this->states[self::STATE_ANNOTATION_TYPE] = new stubAnnotationParserAnnotationTypeState($this); 
     98        $this->states[self::STATE_PARAMS]          = new stubAnnotationParserParamsState($this); 
     99        $this->states[self::STATE_PARAM_NAME]      = new stubAnnotationParserParamNameState($this); 
     100        $this->states[self::STATE_PARAM_VALUE]     = new stubAnnotationParserParamValueState($this); 
     101    } 
     102 
     103    /** 
     104     * change the current state 
     105     * 
     106     * @param  int     $state 
     107     * @param  string  $token  token that should be processed by the state 
     108     */ 
     109    public function changeState($state, $token = null) 
     110    { 
     111        if (isset($this->states[$state]) == false) { 
     112            throw new ReflectionException('Unknown state ' . $state); 
     113        } 
     114         
     115        $this->currentState = $this->states[$state]; 
     116        $this->currentState->selected(); 
     117        if (null != $token) { 
     118            $this->currentState->process($token); 
     119        } 
     120    } 
     121 
     122    /** 
     123     * parse a docblock and return all annotations found 
     124     * 
     125     * @param   string  $docBlock 
     126     * @return  array 
     127     */ 
     128    public function parse($docBlock) 
     129    { 
     130        $this->annotations = null; 
     131        $this->changeState(self::STATE_DEFAULT); 
     132        $len = strlen($docBlock); 
     133        for ($i = 0; $i < $len; $i++) { 
     134            $this->currentState->process($docBlock{$i}); 
     135        } 
     136         
     137        return $this->annotations; 
     138    } 
     139 
     140    /** 
     141     * register a new annotation 
     142     * 
     143     * @param  string  $name 
     144     */ 
     145    public function registerAnnotation($name) 
     146    { 
     147        $this->annotations[$name] = array('type' => $name, 'params' => array()); 
     148        $this->currentAnnotation  = $name; 
     149    } 
     150 
     151    /** 
     152     * register a new annotation param 
     153     * 
     154     * @param  string  $name 
     155     */ 
     156    public function registerAnnotationParam($name) 
     157    { 
     158        $this->currentParam = trim($name); 
     159    } 
     160 
     161    /** 
     162     * register single annotation param 
     163     * 
     164     * @param   string  $value     the value of the param 
     165     * @param   bool    $asString  whether the value is a string or not 
     166     * @throws  ReflectionException 
     167     */ 
     168    public function registerSingleAnnotationParam($value, $asString = false) 
     169    { 
     170        $value = $this->convertAnnotationValue($value, $asString); 
     171        if (count($this->annotations[$this->currentAnnotation]['params']) > 0) { 
     172            throw new ReflectionException('Error parsing annotation ' . $this->currentAnnotation); 
     173        } 
     174         
     175        $this->annotations[$this->currentAnnotation]['params']['value'] = $value; 
     176    } 
     177 
     178    /** 
     179     * set the annoation param value for the current annotation 
     180     * 
     181     * @param   string  $value     the value of the param 
     182     * @param   bool    $asString  whether the value is a string or not 
     183     * @throws  ReflectionException 
     184     */ 
     185    public function setAnnotationParamValue($value, $asString = false) 
     186    { 
     187        $this->annotations[$this->currentAnnotation]['params'][$this->currentParam] = $this->convertAnnotationValue($value, $asString); 
     188    } 
     189 
     190    /** 
     191     * set the type of the current annotation 
     192     * 
     193     * @param  string  $type  type of the annotation 
     194     */ 
     195    public function setAnnotationType($type) 
     196    { 
     197        $this->annotations[$this->currentAnnotation]['type'] = $type; 
     198    } 
     199 
     200    /** 
     201     * convert an annotation value 
     202     * 
     203     * @param   string   $value     the value to convert 
     204     * @param   boolean  $asString  whether value should be treated as string or not 
     205     * @return  mixed 
     206     * @throws  ReflectionException 
     207     * @todo    improve type detection and error handling 
     208     */ 
     209    protected function convertAnnotationValue($value, $asString) 
     210    { 
     211        if (true == $asString) { 
     212            return (string) $value; 
     213        } 
     214         
     215        if ('true' === $value) { 
     216            return true; 
     217        } 
     218         
     219        if ('false' === $value) { 
     220            return false; 
     221        } 
     222         
     223        if (preg_match('/^[+-]?[0-9]+$/', $value) != false) {            
     224            return (integer) $value; 
     225        } 
     226         
     227        $matches = array(); 
     228        if (preg_match('/^([a-zA-Z_]{1}[a-zA-Z\.0-9_]*)\.class/', $value, $matches) != false) { 
     229            return new stubReflectionClass($matches[1]); 
     230        } 
     231         
     232        throw new ReflectionException('Could not determine type of value ' . $value); 
     233    } 
    218234} 
    219235?> 
  • trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAbstractState.php

    r424 r433  
    44 * 
    55 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    67 * @package     stubbles 
    7  * @subpackage  reflection 
     8 * @subpackage  reflection_annotations_parser 
    89 */ 
    9  
    1010/** 
    1111 * Abstract base class for annotion parser states 
    1212 * 
    13  * @author      Stephan Schmidt <schst@stubbles.net> 
    1413 * @package     stubbles 
    15  * @subpackage  reflection 
     14 * @subpackage  reflection_annotations_parser 
    1615 */ 
    17 abstract class stubAnnotationParserAbstractState extends stubBaseObject { 
    18      
    19    /** 
    20     * The parser this state belongs to 
    21    
    22     * @var stubAnnotationParser 
    23     */ 
    24    protected $parser; 
     16abstract class stubAnnotationParserAbstractState extends stubBaseObject 
     17
     18    /** 
     19     * the parser this state belongs to 
     20   
     21     * @var stubAnnotationParser 
     22    */ 
     23    protected $parser; 
    2524 
    26     /** 
    27      * Creare a new state 
    28      * 
    29      * @param stubAnnotationParser $parser 
    30      */ 
    31     public function __construct(stubAnnotationParser $parser) { 
    32         $this->parser = $parser; 
    33     } 
     25    /** 
     26     * constructor 
     27     * 
     28     * @param stubAnnotationParser $parser 
     29     */ 
     30    public function __construct(stubAnnotationParser $parser) 
     31    { 
     32        $this->parser = $parser; 
     33    } 
    3434 
    35     /** 
    36      * Mark this state as the currently used state 
    37      */ 
    38     public function selected() { 
    39 //      print "Selecting state " . get_class($this) . "\n"; 
    40     } 
     35    /** 
     36     * mark this state as the currently used state 
     37     */ 
     38    public function selected() 
     39    { 
     40        // intentionally empty 
     41    } 
    4142} 
    4243?> 
  • trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationNameState.php

    r424 r433  
    44 * 
    55 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    67 * @package     stubbles 
    7  * @subpackage  reflection 
     8 * @subpackage  reflection_annotations_parser 
    89 */ 
    9  
     10stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 
     11                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 
     12); 
    1013/** 
    1114 * Parser is inside the annotation name 
    1215 * 
    13  * @author      Stephan Schmidt <schst@stubbles.net> 
    1416 * @package     stubbles 
    15  * @subpackage  reflection 
    16  * @todo check for allowed tokens in annotation name 
     17 * @subpackage  reflection_annotations_parser 
    1718 */ 
    18 class stubAnnotationParserAnnotationNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState { 
    19     private $name = ''; 
     19class stubAnnotationParserAnnotationNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState 
     20
     21    /** 
     22     * name of the annotation 
     23     * 
     24     * @var  string 
     25     */ 
     26    private $name = ''; 
    2027 
    21     public function selected() { 
    22         parent::selected(); 
    23         $this->name = ''; 
    24     } 
    25          
    26     public function process($token) { 
    27         if ($token === " ") { 
    28             $this->parser->registerAnnotation($this->name); 
    29             $this->parser->changeState(stubAnnotationParser::STATE_ANNOTATION); 
    30             return; 
    31         } 
    32         if ($token === "\n") { 
    33             $this->parser->registerAnnotation($this->name); 
    34             $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
    35             return; 
    36         } 
    37         if ($token === "[") { 
    38             $this->parser->registerAnnotation($this->name); 
    39             $this->parser->changeState(stubAnnotationParser::STATE_ANNOTATION_TYPE); 
    40             return;          
    41         } 
    42         if ($token === "(") { 
    43             $this->parser->registerAnnotation($this->name); 
    44             $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
    45             return;          
    46         } 
    47         $this->name .= $token; 
    48     } 
     28    /** 
     29     * mark this state as the currently used state 
     30     */ 
     31    public function selected() 
     32    { 
     33        parent::selected(); 
     34        $this->name = ''; 
     35    } 
     36 
     37    /** 
     38     * processes a token 
     39     * 
     40     * @param   string  $token 
     41     * @throws  ReflectionException 
     42     */ 
     43    public function process($token) 
     44    { 
     45        switch ($token) { 
     46            case ' ': 
     47                $this->parser->registerAnnotation($this->name); 
     48                $this->parser->changeState(stubAnnotationParser::STATE_ANNOTATION); 
     49                break; 
     50             
     51            case "\n": 
     52                $this->parser->registerAnnotation($this->name); 
     53                $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
     54                break; 
     55             
     56            case '[': 
     57                $this->parser->registerAnnotation($this->name); 
     58                $this->parser->changeState(stubAnnotationParser::STATE_ANNOTATION_TYPE); 
     59                break; 
     60             
     61            case '(': 
     62                $this->parser->registerAnnotation($this->name); 
     63                $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
     64                break; 
     65             
     66            default: 
     67                if (strlen($this->name) == 0 && preg_match('/^[a-zA-Z_]$/', $token) === false) { 
     68                    throw new ReflectionException('Annotation name has to start with a letter or underscore, but starts with ' . $token); 
     69                } elseif (preg_match('/^[a-zA-Z_0-9]$/', $token) === false) { 
     70                    throw new ReflectionException('Annotation name may contain letters, underscores and numbers, but contains ' . $token); 
     71                } 
     72                 
     73                $this->name .= $token; 
     74        } 
     75    } 
    4976} 
    5077?> 
  • trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamNameState.php

    r424 r433  
    44 * 
    55 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    67 * @package     stubbles 
    7  * @subpackage  reflection 
     8 * @subpackage  reflection_annotations_parser 
    89 */ 
    9  
     10stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 
     11                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 
     12); 
    1013/** 
    1114 * Parser is inside an annotation param name 
    1215 * 
    13  * @author      Stephan Schmidt <schst@stubbles.net> 
    1416 * @package     stubbles 
    15  * @subpackage  reflection 
    16  * @todo        Check for allowed tokens in param name 
     17 * @subpackage  reflection_annotations_parser 
    1718 */ 
    18 class stubAnnotationParserParamNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState { 
     19class stubAnnotationParserParamNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState 
     20
     21    /** 
     22     * name of the param 
     23     * 
     24     * @var  string 
     25     */ 
     26    private $name = ''; 
    1927 
    20     private $name = ''; 
     28    /** 
     29     * mark this state as the currently used state 
     30     */ 
     31    public function selected() 
     32    { 
     33        parent::selected(); 
     34        $this->name = ''; 
     35    } 
    2136 
    22     public function selected() { 
    23         parent::selected(); 
    24         $this->name = ''; 
    25     } 
    26          
    27     public function process($token) { 
    28         if ($token === '\'' || $token === '"') { 
    29             $this->parser->registerAnnotationParam('value'); 
    30             $this->parser->changeState(stubAnnotationParser::STATE_PARAM_VALUE, $token); 
    31             return; 
    32         } 
    33         if ($token === '=') { 
    34             $this->parser->registerAnnotationParam($this->name); 
    35             $this->parser->changeState(stubAnnotationParser::STATE_PARAM_VALUE); 
    36             return; 
    37         }        
    38         if ($token === ')') { 
    39             $this->parser->registerSingleAnnotationParam($this->name, false); 
    40             $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
    41             return; 
    42         }        
    43         $this->name .= $token; 
    44     } 
     37    /** 
     38     * processes a token 
     39     * 
     40     * @param   string  $token 
     41     * @throws  ReflectionException 
     42     */ 
     43    public function process($token) 
     44    { 
     45        switch ($token) { 
     46            case "'": 
     47            case '"': 
     48                $this->parser->registerAnnotationParam('value'); 
     49                $this->parser->changeState(stubAnnotationParser::STATE_PARAM_VALUE, $token); 
     50                break; 
     51             
     52            case '=': 
     53                $this->parser->registerAnnotationParam($this->name); 
     54                $this->parser->changeState(stubAnnotationParser::STATE_PARAM_VALUE); 
     55                break; 
     56             
     57            case ')': 
     58                $this->parser->registerSingleAnnotationParam($this->name, false); 
     59                $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
     60                break; 
     61                 
     62            default: 
     63                if (strlen($this->name) == 0 && preg_match('/^[a-zA-Z_]$/', $token) === false) { 
     64                    throw new ReflectionException('Annotation parameter name has to start with a letter or underscore, but starts with ' . $token); 
     65                } elseif (preg_match('/^[a-zA-Z_0-9]$/', $token) === false) { 
     66                    throw new ReflectionException('Annotation parameter name may contain letters, underscores and numbers, but contains ' . $token); 
     67                } 
     68                 
     69                $this->name .= $token; 
     70        } 
     71    } 
    4572} 
    4673?> 
  • trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamValueState.php

    r424 r433  
    44 * 
    55 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    67 * @package     stubbles 
    7  * @subpackage  reflection 
     8 * @subpackage  reflection_annotations_parser 
    89 */ 
    9  
     10stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 
     11                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 
     12); 
    1013/** 
    1114 * Parser is inside an annotation param value 
    1215 * 
    13  * @author      Stephan Schmidt <schst@stubbles.net> 
    1416 * @package     stubbles 
    15  * @subpackage  reflection 
     17 * @subpackage  reflection_annotations_parser 
    1618 */ 
    17 class stubAnnotationParserParamValueState extends stubAnnotationParserAbstractState implements stubAnnotationParserState { 
     19class stubAnnotationParserParamValueState extends stubAnnotationParserAbstractState implements stubAnnotationParserState 
     20
     21    /** 
     22     * type of quotation marks used 
     23     * 
     24     * @var  string 
     25     */ 
     26    private $enclosed   = null; 
     27    /** 
     28     * whether the value is a string or not 
     29     * 
     30     * @var  bool 
     31     */ 
     32    private $isString   = false; 
     33    /** 
     34     * the extracted value 
     35     * 
     36     * @var  string 
     37     */ 
     38    private $value      = ''; 
     39    /** 
     40     * switch whether the next token is escaped or not 
     41     * 
     42     * @var  bool 
     43     */ 
     44    private $escapeNext = false; 
    1845 
    19     private $enclosed = null; 
    20     private $isString = false; 
    21     private $value = ''; 
    22     private $escapeNext = false; 
     46    /** 
     47     * mark this state as the currently used state 
     48     */ 
     49    public function selected() 
     50    { 
     51        parent::selected(); 
     52        $this->value    = ''; 
     53        $this->enclosed = null; 
     54        $this->isString = false; 
     55    } 
    2356 
    24     public function selected() { 
    25         parent::selected(); 
    26         $this->value = ''; 
    27         $this->enclosed = null; 
    28         $this->isString = false; 
    29     } 
    30          
    31     public function process($token) { 
    32          
    33         if ($this->escapeNext === true) { 
    34             $this->value .= $token; 
    35             $this->escapeNext = false; 
    36             return; 
    37         } 
    38          
    39         if ($this->enclosed === null) { 
    40             switch ($token) { 
    41                 case '\'': 
    42                 case '"': 
    43                     $this->enclosed = $token; 
    44                     $this->isString = true; 
    45                     return; 
    46                 case ',': 
    47                     $this->parser->setAnnotationParamValue($this->value, $this->isString); 
    48                     $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
    49                     return; 
    50                 case ')': 
    51                     $this->parser->setAnnotationParamValue($this->value, $this->isString); 
    52                     $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
    53                     return; 
    54             } 
    55         } else { 
    56             switch ($token) { 
    57                 case $this->enclosed: 
    58                     $this->enclosed = null; 
    59                     $this->parser->setAnnotationParamValue($this->value, $this->isString); 
    60                     $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
    61                     return; 
    62                 case '\\': 
    63                     $this->escapeNext = true; 
    64                     return; 
    65             } 
    66         } 
    67         $this->value .= $token; 
    68     } 
     57    /** 
     58     * processes a token 
     59     * 
     60     * @param  string  $token 
     61     */ 
     62    public function process($token) 
     63    { 
     64        if (true === $this->escapeNext) { 
     65            $this->value     .= $token; 
     66            $this->escapeNext = false; 
     67            return; 
     68        } 
     69         
     70        if (null === $this->enclosed) { 
     71            switch ($token) { 
     72                case "'": 
     73                case '"': 
     74                    $this->enclosed = $token; 
     75                    $this->isString = true; 
     76                    return; 
     77                 
     78                case ',': 
     79                    $this->parser->setAnnotationParamValue($this->value, $this->isString); 
     80                    $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
     81                    return; 
     82                 
     83                case ')': 
     84                    $this->parser->setAnnotationParamValue($this->value, $this->isString); 
     85                    $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
     86                    return; 
     87            } 
     88        } else { 
     89            switch ($token) { 
     90                case $this->enclosed: 
     91                    $this->enclosed = null; 
     92                    $this->parser->setAnnotationParamValue($this->value, $this->isString); 
     93                    $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
     94                    return; 
     95                 
     96                case '\\': 
     97                    $this->escapeNext = true; 
     98                    return; 
     99            } 
     100        } 
     101         
     102        $this->value .= $token; 
     103    } 
    69104} 
    70105?> 
  • trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamsState.php

    r424 r433  
    44 * 
    55 * @author      Stephan Schmidt <schst@stubbles.net> 
     6 * @author      Frank Kleine <mikey@stubbles.net> 
    67 * @package     stubbles 
    7  * @subpackage  reflection 
     8 * @subpackage  reflection_annotations_parser 
    89 */ 
    9  
     10stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 
     11                      'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 
     12); 
    1013/** 
    1114 * Parser is inside the annotation params 
    1215 * 
    13  * @author      Stephan Schmidt <schst@stubbles.net> 
    1416 * @package     stubbles 
    15  * @subpackage  reflection 
     17 * @subpackage  reflection_annotations_parser 
    1618 */ 
    17 class stubAnnotationParserParamsState extends stubAnnotationParserAbstractState implements stubAnnotationParserState { 
    18  
    19     public function selected() { 
    20         parent::selected(); 
    21     } 
    22          
    23     public function process($token) { 
    24         if ($token === ')') { 
    25             $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
    26             return; 
    27         } 
    28         if ($token === ',') { 
    29             $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
    30             return; 
    31         } 
    32         if ($token === ' ' || $token === "\n" || $token === '*') { 
    33             return; 
    34         } 
    35         $this->parser->changeState(stubAnnotationParser::STATE_PARAM_NAME, $token); 
    36     } 
     19class stubAnnotationParserParamsState extends stubAnnotationParserAbstractState implements stubAnnotationParserState 
     20
     21    /** 
     22     * processes a token 
     23     * 
     24     * @param  string  $token 
     25     */ 
     26    public function process($token) 
     27    { 
     28        switch ($token) { 
     29            case ')': 
     30                $this->parser->changeState(stubAnnotationParser::STATE_DEFAULT); 
     31                break; 
     32             
     33            case ',': 
     34                $this->parser->changeState(stubAnnotationParser::STATE_PARAMS); 
     35                break; 
     36             
     37            case ' ': 
     38            case "\n": 
     39            case "\t": 
     40            case '*': 
     41                break; 
     42                 
     43            default: 
     44                $this->parser->changeState(stubAnnotationParser::STATE_PARAM_NAME, $token); 
     45        } 
     46    } 
    3747} 
    3848?>