Yaffs site version 1.1
[yaffs-website] / vendor / symfony / class-loader / ClassMapGenerator.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\ClassLoader;
13
14 if (!defined('SYMFONY_TRAIT')) {
15     if (\PHP_VERSION_ID >= 50400) {
16         define('SYMFONY_TRAIT', T_TRAIT);
17     } else {
18         define('SYMFONY_TRAIT', 0);
19     }
20 }
21
22 /**
23  * ClassMapGenerator.
24  *
25  * @author Gyula Sallai <salla016@gmail.com>
26  */
27 class ClassMapGenerator
28 {
29     /**
30      * Generate a class map file.
31      *
32      * @param array|string $dirs Directories or a single path to search in
33      * @param string       $file The name of the class map file
34      */
35     public static function dump($dirs, $file)
36     {
37         $dirs = (array) $dirs;
38         $maps = array();
39
40         foreach ($dirs as $dir) {
41             $maps = array_merge($maps, static::createMap($dir));
42         }
43
44         file_put_contents($file, sprintf('<?php return %s;', var_export($maps, true)));
45     }
46
47     /**
48      * Iterate over all files in the given directory searching for classes.
49      *
50      * @param \Iterator|string $dir The directory to search in or an iterator
51      *
52      * @return array A class map array
53      */
54     public static function createMap($dir)
55     {
56         if (is_string($dir)) {
57             $dir = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir));
58         }
59
60         $map = array();
61
62         foreach ($dir as $file) {
63             if (!$file->isFile()) {
64                 continue;
65             }
66
67             $path = $file->getRealPath() ?: $file->getPathname();
68
69             if (pathinfo($path, PATHINFO_EXTENSION) !== 'php') {
70                 continue;
71             }
72
73             $classes = self::findClasses($path);
74
75             if (\PHP_VERSION_ID >= 70000) {
76                 // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
77                 gc_mem_caches();
78             }
79
80             foreach ($classes as $class) {
81                 $map[$class] = $path;
82             }
83         }
84
85         return $map;
86     }
87
88     /**
89      * Extract the classes in the given file.
90      *
91      * @param string $path The file to check
92      *
93      * @return array The found classes
94      */
95     private static function findClasses($path)
96     {
97         $contents = file_get_contents($path);
98         $tokens = token_get_all($contents);
99
100         $classes = array();
101
102         $namespace = '';
103         for ($i = 0; isset($tokens[$i]); ++$i) {
104             $token = $tokens[$i];
105
106             if (!isset($token[1])) {
107                 continue;
108             }
109
110             $class = '';
111
112             switch ($token[0]) {
113                 case T_NAMESPACE:
114                     $namespace = '';
115                     // If there is a namespace, extract it
116                     while (isset($tokens[++$i][1])) {
117                         if (in_array($tokens[$i][0], array(T_STRING, T_NS_SEPARATOR))) {
118                             $namespace .= $tokens[$i][1];
119                         }
120                     }
121                     $namespace .= '\\';
122                     break;
123                 case T_CLASS:
124                 case T_INTERFACE:
125                 case SYMFONY_TRAIT:
126                     // Skip usage of ::class constant
127                     $isClassConstant = false;
128                     for ($j = $i - 1; $j > 0; --$j) {
129                         if (!isset($tokens[$j][1])) {
130                             break;
131                         }
132
133                         if (T_DOUBLE_COLON === $tokens[$j][0]) {
134                             $isClassConstant = true;
135                             break;
136                         } elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
137                             break;
138                         }
139                     }
140
141                     if ($isClassConstant) {
142                         break;
143                     }
144
145                     // Find the classname
146                     while (isset($tokens[++$i][1])) {
147                         $t = $tokens[$i];
148                         if (T_STRING === $t[0]) {
149                             $class .= $t[1];
150                         } elseif ('' !== $class && T_WHITESPACE === $t[0]) {
151                             break;
152                         }
153                     }
154
155                     $classes[] = ltrim($namespace.$class, '\\');
156                     break;
157                 default:
158                     break;
159             }
160         }
161
162         return $classes;
163     }
164 }