/src/Token.php

https://github.com/GunioRobot/phpca · PHP · 433 lines · 154 code · 45 blank · 234 comment · 9 complexity · 80020e643d746484ba393c1bbe015626 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright (c) 2009 Stefan Priebsch <stefan@priebsch.de>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. *
  12. * * Redistributions in binary form must reproduce the above copyright notice,
  13. * this list of conditions and the following disclaimer in the documentation
  14. * and/or other materials provided with the distribution.
  15. *
  16. * * Neither the name of Stefan Priebsch nor the names of contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  22. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
  24. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  25. * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. * POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * @package PHPca
  33. * @author Stefan Priebsch <stefan@priebsch.de>
  34. * @copyright Stefan Priebsch <stefan@priebsch.de>. All rights reserved.
  35. * @license BSD License
  36. */
  37. namespace spriebsch\PHPca;
  38. /**
  39. * The Token class wraps one PHP tokenizer token.
  40. * Each token knows its line and column in the source file.
  41. * Where no PHP tokens exist (brackets, braces, etc.),
  42. * we have defined our own in Constants.
  43. *
  44. * @author Stefan Priebsch <stefan@priebsch.de>
  45. * @copyright Stefan Priebsch <stefan@priebsch.de>. All rights reserved.
  46. * @todo a token should know the function/method it is in
  47. * @todo a token should know the class it is in
  48. * @todo a token should know the namespace it is in (probably part of fn and class name thing)
  49. */
  50. class Token
  51. {
  52. /**
  53. * @var int
  54. */
  55. protected $id;
  56. /**
  57. * @var string
  58. */
  59. protected $text;
  60. /**
  61. * @var int
  62. */
  63. protected $line;
  64. /**
  65. * @var int
  66. */
  67. protected $column;
  68. /**
  69. * @var string
  70. */
  71. protected $file;
  72. /**
  73. * @var string
  74. */
  75. protected $namespace;
  76. /**
  77. * @var string
  78. */
  79. protected $class;
  80. /**
  81. * @var string
  82. */
  83. protected $interface;
  84. /**
  85. * @var string
  86. */
  87. protected $function;
  88. /**
  89. * @var int
  90. */
  91. protected $blockLevel;
  92. /**
  93. * Constructs the object
  94. *
  95. * @param int $id
  96. * @param string $text
  97. * @param int $line
  98. * @param int $column
  99. * @return void
  100. */
  101. public function __construct($id, $text, $line = 0, $column = 0)
  102. {
  103. $this->id = $id;
  104. $this->text = $text;
  105. $this->line = $line;
  106. $this->column = $column;
  107. }
  108. /**
  109. * Set the file name the token is part of.
  110. *
  111. * @param string $file
  112. * @return null
  113. */
  114. public function setFile($file)
  115. {
  116. $this->file = $file;
  117. }
  118. /**
  119. * Returns the file name the token is part of.
  120. *
  121. * @return string
  122. */
  123. public function getFile()
  124. {
  125. return $this->file;
  126. }
  127. /**
  128. * Set the namespace the token is part of.
  129. *
  130. * @param string $file
  131. * @return null
  132. */
  133. public function setNamespace($namespace)
  134. {
  135. $this->namespace = $namespace;
  136. }
  137. /**
  138. * Returns the namespace the token is part of.
  139. *
  140. * @return string
  141. */
  142. public function getNamespace()
  143. {
  144. return $this->namespace;
  145. }
  146. /**
  147. * Set the class the token is part of.
  148. *
  149. * @param string $file
  150. * @return null
  151. */
  152. public function setClass($class)
  153. {
  154. $this->class = $class;
  155. }
  156. /**
  157. * Returns the class the token is part of.
  158. *
  159. * @return string
  160. */
  161. public function getClass()
  162. {
  163. return $this->class;
  164. }
  165. /**
  166. * Set the interface the token is part of.
  167. *
  168. * @param string $interface
  169. * @return null
  170. */
  171. public function setInterface($interface)
  172. {
  173. $this->interface = $interface;
  174. }
  175. /**
  176. * Returns the interface the token is part of.
  177. *
  178. * @return string
  179. */
  180. public function getInterface()
  181. {
  182. return $this->interface;
  183. }
  184. /**
  185. * Set the function the token is part of.
  186. *
  187. * @param string $function
  188. */
  189. public function setFunction($function)
  190. {
  191. $this->function = $function;
  192. }
  193. /**
  194. * Returns the function the token is part of.
  195. *
  196. * @return string
  197. */
  198. public function getFunction()
  199. {
  200. return $this->function;
  201. }
  202. /**
  203. * Set the block level (number of open {'s) the token is in.
  204. *
  205. * @param int $level
  206. */
  207. public function setBlockLevel($blockLevel)
  208. {
  209. $this->blockLevel = $blockLevel;
  210. }
  211. /**
  212. * Returns the block level the token is part of.
  213. *
  214. * @return int
  215. */
  216. public function getBlockLevel()
  217. {
  218. return $this->blockLevel;
  219. }
  220. /**
  221. * Returns the numeric ID of the constant representing this token.
  222. *
  223. * @return int
  224. */
  225. public function getId()
  226. {
  227. return $this->id;
  228. }
  229. /**
  230. * Returns the name of the constant representing this token as a string.
  231. *
  232. * @return string
  233. */
  234. public function getName()
  235. {
  236. return Constants::getTokenName($this->id);
  237. }
  238. /**
  239. * Returns the text (contents) of this token.
  240. *
  241. * @return string
  242. */
  243. public function getText()
  244. {
  245. return $this->text;
  246. }
  247. /**
  248. * Returns the source code line the token starts on.
  249. *
  250. * @return int
  251. */
  252. public function getStartLine()
  253. {
  254. // For whitespace with leading line breaks, we display
  255. // the "next" line number instead of the actual line number where the whitespace token starts
  256. if ($this->id == T_WHITESPACE) {
  257. preg_match("/^\\n*/m", $this->text, $matches);
  258. return $this->line + strlen($matches[0]);
  259. }
  260. return $this->line;
  261. }
  262. /**
  263. * Returns the source code line the token starts on.
  264. *
  265. * @return int
  266. */
  267. public function getLine()
  268. {
  269. return $this->getStartLine();
  270. }
  271. /**
  272. * Returns the source code column the token starts on.
  273. *
  274. * @return int
  275. */
  276. public function getStartColumn()
  277. {
  278. // If whitespace starts with newlines, we claim to be on column 1 of the "next" line
  279. if ($this->id == T_WHITESPACE) {
  280. if ($this->getStartLine() != $this->line) {
  281. return 1;
  282. }
  283. }
  284. return $this->column;
  285. }
  286. /**
  287. * Returns the source code column the token starts on.
  288. *
  289. * @return int
  290. */
  291. public function getColumn()
  292. {
  293. return $this->getStartColumn();
  294. }
  295. /**
  296. * Returns the line number the token ends on.
  297. *
  298. * @return int
  299. */
  300. public function getEndLine()
  301. {
  302. return $this->line + $this->getNewLineCount();
  303. }
  304. /**
  305. * Returns the column number the token ends on.
  306. *
  307. * @return int
  308. */
  309. public function getEndColumn()
  310. {
  311. if ($this->hasNewline()) {
  312. return 1 + $this->getTrailingWhitespaceCount();
  313. }
  314. return $this->column + $this->getLength();
  315. }
  316. /**
  317. * Returns the length in characters of this token.
  318. *
  319. * @return int
  320. */
  321. public function getLength()
  322. {
  323. return strlen($this->text);
  324. }
  325. /**
  326. * Check whether the token contains any new line characters.
  327. *
  328. * @return int
  329. */
  330. public function hasNewLine()
  331. {
  332. return strstr($this->text, "\n") !== false;
  333. }
  334. /**
  335. * Returns new line count of the token's text.
  336. * Only counts \n, no \r characters.
  337. *
  338. * @return int
  339. */
  340. public function getNewLineCount()
  341. {
  342. return substr_count($this->text, "\n");
  343. }
  344. /**
  345. * Check whether the token's text contains whitespace
  346. * (CR, LF, tab, or blank).
  347. *
  348. * @return bool
  349. */
  350. public function hasWhitespace()
  351. {
  352. return strstr($this->text, "\r") !== false ||
  353. strstr($this->text, "\n") !== false ||
  354. strstr($this->text, "\t") !== false ||
  355. strstr($this->text, " ") !== false;
  356. }
  357. /**
  358. * Returns the trailing whitespace, that is the whitespace after
  359. * the last new line (if present).
  360. *
  361. * @return string
  362. */
  363. public function getTrailingWhitespace()
  364. {
  365. // no newline: count number of trailing whitespace characters
  366. if (!$this->hasNewLine()) {
  367. preg_match('/\s*$/', $this->text, $matches);
  368. return $matches[0];
  369. }
  370. // find last newline character
  371. $pos = strrpos($this->text, "\n");
  372. // no trailing whitespace if newline is the last character
  373. if ($pos >= strlen($this->text) - 1) {
  374. return '';
  375. }
  376. return substr($this->text, $pos + 1);
  377. }
  378. /**
  379. * Returns count of trailing whitespace characters.
  380. *
  381. * @return int
  382. */
  383. public function getTrailingWhitespaceCount()
  384. {
  385. return strlen($this->getTrailingWhitespace());
  386. }
  387. }
  388. ?>