PageRenderTime 54ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/Reflection/src/doc_comment_parser.php

https://github.com/Yannix/zetacomponents
PHP | 265 lines | 123 code | 26 blank | 116 comment | 25 complexity | 1dc37bdba81f40023e315cbb01540cc3 MD5 | raw file
  1. <?php
  2. /**
  3. * File containing the ezcReflectionDocCommentParserImpl class.
  4. *
  5. * Licensed to the Apache Software Foundation (ASF) under one
  6. * or more contributor license agreements. See the NOTICE file
  7. * distributed with this work for additional information
  8. * regarding copyright ownership. The ASF licenses this file
  9. * to you under the Apache License, Version 2.0 (the
  10. * "License"); you may not use this file except in compliance
  11. * with the License. You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing,
  16. * software distributed under the License is distributed on an
  17. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. * KIND, either express or implied. See the License for the
  19. * specific language governing permissions and limitations
  20. * under the License.
  21. *
  22. * @package Reflection
  23. * @version //autogen//
  24. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  25. */
  26. /**
  27. * Provides structured data from PHP Documentor comments
  28. *
  29. * Parser is implemented as state based parser using a state transisiton
  30. * table consisting of transition rules for empty and non-empty lines.
  31. *
  32. * @package Reflection
  33. * @version //autogen//
  34. * @author Stefan Marr <mail@stefan-marr.de>
  35. * @author Falko Menge <mail@falko-menge.de>
  36. */
  37. class ezcReflectionDocCommentParserImpl implements ezcReflectionDocCommentParser {
  38. const BEGINNING = 10;
  39. const SHORT_DESC = 0;
  40. const LONG_DESC = 1;
  41. const ANNOTATIONS = 2;
  42. /**
  43. * @var string
  44. */
  45. protected $docComment;
  46. /**
  47. * @var int STATE
  48. */
  49. protected $state = self::BEGINNING;
  50. /**
  51. * @var array(int=>int)
  52. */
  53. protected $stateTable = array(
  54. true => array ( // empty lines
  55. self::BEGINNING => self::BEGINNING,
  56. self::SHORT_DESC => self::LONG_DESC,
  57. self::LONG_DESC => self::LONG_DESC,
  58. self::ANNOTATIONS => self::ANNOTATIONS
  59. ),
  60. false => array ( // non empty lines
  61. self::BEGINNING => self::SHORT_DESC,
  62. self::SHORT_DESC => self::SHORT_DESC,
  63. self::LONG_DESC => self::LONG_DESC,
  64. self::ANNOTATIONS => self::ANNOTATIONS
  65. )
  66. );
  67. /**
  68. * @var ezcReflectionAnnotation
  69. */
  70. protected $lastAnnotation = null;
  71. /**
  72. * @var string
  73. */
  74. protected $shortDesc;
  75. /**
  76. * @var string
  77. */
  78. protected $longDesc;
  79. /**
  80. * @var ezcReflectionAnnotation[]
  81. */
  82. protected $annotations;
  83. /**
  84. * Constructs an instance of ezcReflectionDocCommentParserImpl
  85. *
  86. * @return ezcReflectionDocCommentParserImpl
  87. */
  88. public function __construct() {
  89. $this->annotations = array();
  90. }
  91. /**
  92. * Initialize parsing of the given documentation fragment.
  93. * Results can be retrieved after completion by the getters provided.
  94. *
  95. * @param string $docComment
  96. * @return void
  97. * @see interfaces/ezcReflectionDocCommentParser#parse($docComment)
  98. */
  99. public function parse($docComment) {
  100. $this->docComment = $docComment;
  101. $lines = explode("\n", $this->docComment);
  102. foreach ($lines as $line) {
  103. $line = $this->extractContentFromDocCommentLine($line);
  104. // in some states we need to do something
  105. if (!empty($line)) {
  106. if ($line[0] == '@') {
  107. $this->state = self::ANNOTATIONS;
  108. $this->parseAnnotation($line);
  109. }
  110. elseif ($this->state == self::ANNOTATIONS) {
  111. $this->parseAnnotation($line);
  112. }
  113. else {
  114. if ($this->state == self::SHORT_DESC
  115. or $this->state == self::BEGINNING) {
  116. $this->shortDesc .= $line . "\n";
  117. }
  118. elseif ($this->state == self::LONG_DESC) {
  119. $this->longDesc .= $line . "\n";
  120. }
  121. }
  122. }
  123. else if ($this->state == self::LONG_DESC) {
  124. $this->longDesc .= "\n";
  125. }
  126. //next state
  127. $this->state = $this->stateTable[empty($line)][$this->state];
  128. }
  129. $this->shortDesc = trim($this->shortDesc);
  130. $this->longDesc = trim($this->longDesc);
  131. }
  132. /**
  133. * @param string $line
  134. * @return string
  135. */
  136. protected function extractContentFromDocCommentLine($line) {
  137. $line = trim($line);
  138. if (substr($line, -2) == '*/') {
  139. $line = substr($line, 0, -2);
  140. }
  141. while (strlen($line) > 0 and ($line[0] == '/' or $line[0] == '*')) {
  142. $line = substr($line, 1);
  143. }
  144. return trim($line);
  145. }
  146. /**
  147. * @param string $line
  148. * @return void
  149. */
  150. protected function parseAnnotation($line) {
  151. if (strlen($line) > 0) {
  152. if ($line[0] == '@') {
  153. $line = substr($line, 1);
  154. $words = preg_split('/\s+/', $line, 4); // split the line by whitespace into up to 4 parts
  155. $annotation = ezcReflectionAnnotationFactory::createAnnotation($words[0], $words);
  156. $this->annotations[$annotation->getName()][] = $annotation;
  157. $this->lastAnnotation = $annotation;
  158. }
  159. else {
  160. //no leading @, it is assumed a description is multiline
  161. if ($this->lastAnnotation != null) {
  162. $this->lastAnnotation->addDescriptionLine($line);
  163. }
  164. }
  165. }
  166. }
  167. /**
  168. * Returns an array of annotations with a given name
  169. *
  170. * @param string $name
  171. * @return ezcReflectionAnnotation[]
  172. */
  173. public function getAnnotationsByName($name) {
  174. if (isset($this->annotations[$name])) {
  175. return $this->annotations[$name];
  176. }
  177. else {
  178. return array();
  179. }
  180. }
  181. /**
  182. * @return ezcReflectionAnnotation[]
  183. */
  184. public function getAnnotations() {
  185. $result = array();
  186. foreach ($this->annotations as $annotations) {
  187. foreach ($annotations as $annotation) {
  188. $result[] = $annotation;
  189. }
  190. }
  191. return $result;
  192. }
  193. /**
  194. * @return ezcReflectionAnnotationParam[]
  195. */
  196. public function getParamAnnotations() {
  197. return $this->getAnnotationsByName('param');
  198. }
  199. /**
  200. * @return ezcReflectionAnnotationVar[]
  201. */
  202. public function getVarAnnotations() {
  203. return $this->getAnnotationsByName('var');
  204. }
  205. /**
  206. * Return an array of return annotations
  207. *
  208. * @return ezcReflectionAnnotationReturn[]
  209. */
  210. public function getReturnAnnotations() {
  211. return $this->getAnnotationsByName('return');
  212. }
  213. /**
  214. * Checks whether a annotation is used
  215. *
  216. * @param string $with name of used annotation
  217. * @return boolean
  218. */
  219. public function hasAnnotation($with) {
  220. return isset($this->annotations[$with]);
  221. }
  222. /**
  223. * Returns the short description from the source code documentation
  224. *
  225. * @return string Short description
  226. */
  227. public function getShortDescription() {
  228. return $this->shortDesc;
  229. }
  230. /**
  231. * Returns the long description from the source code documentation
  232. *
  233. * @return string Long description
  234. */
  235. public function getLongDescription() {
  236. return $this->longDesc;
  237. }
  238. }
  239. ?>