5 * Copyright (c) 2002-2011, Sebastian Bergmann <sebastian@phpunit.de>.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * * Neither the name of Sebastian Bergmann nor the names of his
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
39 * @author Sebastian Bergmann <sebastian@phpunit.de>
40 * @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de>
41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
42 * @link http://www.phpunit.de/
43 * @since File available since Release 3.4.0
46 if (!defined('T_NAMESPACE')) {
47 define('T_NAMESPACE', 377);
55 * @author Sebastian Bergmann <sebastian@phpunit.de>
56 * @copyright 2002-2011 Sebastian Bergmann <sebastian@phpunit.de>
57 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
58 * @version Release: 3.5.13
59 * @link http://www.phpunit.de/
60 * @since Class available since Release 3.4.0
62 class PHPUnit_Util_File
67 protected static $cache = array();
70 * Returns information on the classes declared in a sourcefile.
72 * @param string $filename
75 public static function getClassesInFile($filename)
77 if (!isset(self::$cache[$filename])) {
78 self::$cache[$filename] = self::parseFile($filename);
81 return self::$cache[$filename];
85 * Parses a file for class and method information.
87 * @param string $filename
90 protected static function parseFile($filename)
94 $tokens = token_get_all(
95 file_get_contents($filename)
97 $numTokens = count($tokens);
100 $currentBlock = FALSE;
101 $currentNamespace = FALSE;
102 $currentClass = FALSE;
103 $currentFunction = FALSE;
104 $currentFunctionStartLine = FALSE;
105 $currentFunctionTokens = array();
106 $currentDocComment = FALSE;
107 $currentSignature = FALSE;
108 $currentSignatureStartToken = FALSE;
110 for ($i = 0; $i < $numTokens; $i++) {
111 if ($currentFunction !== FALSE) {
112 $currentFunctionTokens[] = $tokens[$i];
115 if (is_string($tokens[$i])) {
116 if ($tokens[$i] == '{') {
117 if ($currentBlock == T_CLASS) {
118 $block = $currentClass;
121 else if ($currentBlock == T_FUNCTION) {
122 $currentSignature = '';
124 for ($j = $currentSignatureStartToken; $j < $i; $j++) {
125 if (is_string($tokens[$j])) {
126 $currentSignature .= $tokens[$j];
128 $currentSignature .= $tokens[$j][1];
132 $currentSignature = trim($currentSignature);
134 $block = $currentFunction;
135 $currentSignatureStartToken = FALSE;
142 array_push($blocks, $block);
144 $currentBlock = FALSE;
147 else if ($tokens[$i] == '}') {
148 $block = array_pop($blocks);
150 if ($block !== FALSE && $block !== NULL) {
151 if ($block == $currentFunction) {
152 if ($currentDocComment !== FALSE) {
153 $docComment = $currentDocComment;
154 $currentDocComment = FALSE;
160 'docComment' => $docComment,
161 'signature' => $currentSignature,
162 'startLine' => $currentFunctionStartLine,
164 'tokens' => $currentFunctionTokens
167 if ($currentClass !== FALSE) {
168 $result[$currentClass]['methods'][$currentFunction] = $tmp;
171 $currentFunction = FALSE;
172 $currentFunctionStartLine = FALSE;
173 $currentFunctionTokens = array();
174 $currentSignature = FALSE;
177 else if ($block == $currentClass) {
178 $result[$currentClass]['endLine'] = $line;
180 $currentClass = FALSE;
181 $currentClassStartLine = FALSE;
189 switch ($tokens[$i][0]) {
190 case T_HALT_COMPILER: {
196 $currentNamespace = $tokens[$i+2][1];
198 for ($j = $i+3; $j < $numTokens; $j += 2) {
199 if ($tokens[$j][0] == T_NS_SEPARATOR) {
200 $currentNamespace .= '\\' . $tokens[$j+1][1];
209 $currentBlock = T_CURLY_OPEN;
210 array_push($blocks, $currentBlock);
214 case T_DOLLAR_OPEN_CURLY_BRACES: {
215 $currentBlock = T_DOLLAR_OPEN_CURLY_BRACES;
216 array_push($blocks, $currentBlock);
221 $currentBlock = T_CLASS;
223 if ($currentNamespace === FALSE) {
224 $currentClass = $tokens[$i+2][1];
226 $currentClass = $currentNamespace . '\\' .
230 if ($currentDocComment !== FALSE) {
231 $docComment = $currentDocComment;
232 $currentDocComment = FALSE;
237 $result[$currentClass] = array(
238 'methods' => array(),
239 'docComment' => $docComment,
246 if (!((is_array($tokens[$i+2]) &&
247 $tokens[$i+2][0] == T_STRING) ||
248 (is_string($tokens[$i+2]) &&
249 $tokens[$i+2] == '&' &&
250 is_array($tokens[$i+3]) &&
251 $tokens[$i+3][0] == T_STRING))) {
255 $currentBlock = T_FUNCTION;
256 $currentFunctionStartLine = $line;
259 $currentSignatureStartToken = $i - 1;
262 switch ($tokens[$currentSignatureStartToken][0]) {
270 $currentSignatureStartToken--;
275 $currentSignatureStartToken++;
282 if (isset($tokens[$i+2][1])) {
283 $functionName = $tokens[$i+2][1];
286 else if (isset($tokens[$i+3][1])) {
287 $functionName = $tokens[$i+3][1];
290 if ($currentNamespace === FALSE) {
291 $currentFunction = $functionName;
293 $currentFunction = $currentNamespace . '\\' .
299 case T_DOC_COMMENT: {
300 $currentDocComment = $tokens[$i][1];
305 $line += substr_count($tokens[$i][1], "\n");