Changeset 433
- Timestamp:
- 03/28/07 23:46:54 (1 year ago)
- Files:
-
- trunk/docroot/annotationParser.php (modified) (3 diffs)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser (moved) (moved from trunk/src/main/php/net/stubbles/reflection/parser)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParser.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAbstractState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationNameState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamNameState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamValueState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamsState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationTypeState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserDefaultState.php (modified) (1 diff)
- trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserState.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/docroot/annotationParser.php
r424 r433 3 3 require_once '../src/main/php/net/stubbles/stubClassLoader.php'; 4 4 stubClassLoader::load('net.stubbles.reflection.reflection', 5 'net.stubbles.reflection.parser.stubAnnotationParser'); 6 5 'net.stubbles.reflection.annotations.parser.stubAnnotationParser' 6 ); 7 7 /** 8 8 * This is some text.... … … 17 17 * @SingleValue(42) 18 18 * @SingleStringValue('This is a string with chars like = or ,') 19 * @WithEscaped(foo='This string contain ing\' and \\, which is possible using escaping...')19 * @WithEscaped(foo='This string contains \' and \\, which is possible using escaping...') 20 20 * @Multiline(one=1, 21 21 * two=2) … … 26 26 */ 27 27 class MyTestClass { 28 28 // intentionally empty 29 29 } 30 30 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(); 35 34 $annotations = $parser->parse($docBlock); 36 35 echo '<pre>'; 37 36 print_r($annotations); 38 37 trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParser.php
r424 r433 1 1 <?php 2 2 /** 3 * Parser to parse Java-Style annotations 3 * Parser to parse Java-Style annotations. 4 4 * 5 5 * @author Stephan Schmidt <schst@stubbles.net> 6 * @author Frank Kleine <mikey@stubbles.net> 6 7 * @package stubbles 7 * @subpackage reflection 8 * @subpackage reflection_annotations_parser 8 9 */ 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 10 stubClassLoader::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 ); 19 20 /** 20 * Parser to parse Java-Style annotations 21 * Parser to parse Java-Style annotations. 21 22 * 22 * @author Stephan Schmidt <schst@stubbles.net>23 23 * @package stubbles 24 * @subpackage reflection 25 * @todo Improve error handling26 * @todo Write unit tests24 * @subpackage reflection_annotations_parser 25 * @todo improve error handling 26 * @todo write unit tests 27 27 */ 28 28 class stubAnnotationParser 29 29 { 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 } 218 234 } 219 235 ?> trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAbstractState.php
r424 r433 4 4 * 5 5 * @author Stephan Schmidt <schst@stubbles.net> 6 * @author Frank Kleine <mikey@stubbles.net> 6 7 * @package stubbles 7 * @subpackage reflection 8 * @subpackage reflection_annotations_parser 8 9 */ 9 10 10 /** 11 11 * Abstract base class for annotion parser states 12 12 * 13 * @author Stephan Schmidt <schst@stubbles.net>14 13 * @package stubbles 15 * @subpackage reflection 14 * @subpackage reflection_annotations_parser 16 15 */ 17 abstract class stubAnnotationParserAbstractState extends stubBaseObject {18 19 /**20 * The parser this state belongs to21 *22 * @varstubAnnotationParser23 */24 protected $parser;16 abstract class stubAnnotationParserAbstractState extends stubBaseObject 17 { 18 /** 19 * the parser this state belongs to 20 * 21 * @var stubAnnotationParser 22 */ 23 protected $parser; 25 24 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 } 34 34 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 } 41 42 } 42 43 ?> trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationNameState.php
r424 r433 4 4 * 5 5 * @author Stephan Schmidt <schst@stubbles.net> 6 * @author Frank Kleine <mikey@stubbles.net> 6 7 * @package stubbles 7 * @subpackage reflection 8 * @subpackage reflection_annotations_parser 8 9 */ 9 10 stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 11 'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 12 ); 10 13 /** 11 14 * Parser is inside the annotation name 12 15 * 13 * @author Stephan Schmidt <schst@stubbles.net>14 16 * @package stubbles 15 * @subpackage reflection 16 * @todo check for allowed tokens in annotation name 17 * @subpackage reflection_annotations_parser 17 18 */ 18 class stubAnnotationParserAnnotationNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState { 19 private $name = ''; 19 class stubAnnotationParserAnnotationNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState 20 { 21 /** 22 * name of the annotation 23 * 24 * @var string 25 */ 26 private $name = ''; 20 27 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 } 49 76 } 50 77 ?> trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamNameState.php
r424 r433 4 4 * 5 5 * @author Stephan Schmidt <schst@stubbles.net> 6 * @author Frank Kleine <mikey@stubbles.net> 6 7 * @package stubbles 7 * @subpackage reflection 8 * @subpackage reflection_annotations_parser 8 9 */ 9 10 stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 11 'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 12 ); 10 13 /** 11 14 * Parser is inside an annotation param name 12 15 * 13 * @author Stephan Schmidt <schst@stubbles.net>14 16 * @package stubbles 15 * @subpackage reflection 16 * @todo Check for allowed tokens in param name 17 * @subpackage reflection_annotations_parser 17 18 */ 18 class stubAnnotationParserParamNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState { 19 class stubAnnotationParserParamNameState extends stubAnnotationParserAbstractState implements stubAnnotationParserState 20 { 21 /** 22 * name of the param 23 * 24 * @var string 25 */ 26 private $name = ''; 19 27 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 } 21 36 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 } 45 72 } 46 73 ?> trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamValueState.php
r424 r433 4 4 * 5 5 * @author Stephan Schmidt <schst@stubbles.net> 6 * @author Frank Kleine <mikey@stubbles.net> 6 7 * @package stubbles 7 * @subpackage reflection 8 * @subpackage reflection_annotations_parser 8 9 */ 9 10 stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 11 'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 12 ); 10 13 /** 11 14 * Parser is inside an annotation param value 12 15 * 13 * @author Stephan Schmidt <schst@stubbles.net>14 16 * @package stubbles 15 * @subpackage reflection 17 * @subpackage reflection_annotations_parser 16 18 */ 17 class stubAnnotationParserParamValueState extends stubAnnotationParserAbstractState implements stubAnnotationParserState { 19 class 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; 18 45 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 } 23 56 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 } 69 104 } 70 105 ?> trunk/src/main/php/net/stubbles/reflection/annotations/parser/stubAnnotationParserAnnotationParamsState.php
r424 r433 4 4 * 5 5 * @author Stephan Schmidt <schst@stubbles.net> 6 * @author Frank Kleine <mikey@stubbles.net> 6 7 * @package stubbles 7 * @subpackage reflection 8 * @subpackage reflection_annotations_parser 8 9 */ 9 10 stubClassLoader::load('net.stubbles.reflection.annotations.parser.stubAnnotationParserAbstractState', 11 'net.stubbles.reflection.annotations.parser.stubAnnotationParserState' 12 ); 10 13 /** 11 14 * Parser is inside the annotation params 12 15 * 13 * @author Stephan Schmidt <schst@stubbles.net>14 16 * @package stubbles 15 * @subpackage reflection 17 * @subpackage reflection_annotations_parser 16 18 */ 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 } 19 class 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 } 37 47 } 38 48 ?>
