comparison vendor/squizlabs/php_codesniffer/autoload.php @ 4:a9cd425dd02b

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:11:55 +0000
parents
children 12f9dff5fda9
comparison
equal deleted inserted replaced
3:307d7a7fd348 4:a9cd425dd02b
1 <?php
2 /**
3 * Autoloads files for PHP_CodeSniffer and tracks what has been loaded.
4 *
5 * Due to different namespaces being used for custom coding standards,
6 * the autoloader keeps track of what class is loaded after a file is included,
7 * even if the file is ultimately included by another autoloader (such as composer).
8 *
9 * This allows PHP_CodeSniffer to request the class name after loading a class
10 * when it only knows the filename, without having to parse the file to find it.
11 *
12 * @author Greg Sherwood <gsherwood@squiz.net>
13 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
14 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
15 */
16
17 namespace PHP_CodeSniffer;
18
19 if (class_exists('PHP_CodeSniffer\Autoload', false) === false) {
20 class Autoload
21 {
22
23 /**
24 * The composer autoloader.
25 *
26 * @var Composer\Autoload\ClassLoader
27 */
28 private static $composerAutoloader = null;
29
30 /**
31 * A mapping of file names to class names.
32 *
33 * @var array<string, string>
34 */
35 private static $loadedClasses = [];
36
37 /**
38 * A mapping of class names to file names.
39 *
40 * @var array<string, string>
41 */
42 private static $loadedFiles = [];
43
44 /**
45 * A list of additional directories to search during autoloading.
46 *
47 * This is typically a list of coding standard directories.
48 *
49 * @var string[]
50 */
51 private static $searchPaths = [];
52
53
54 /**
55 * Loads a class.
56 *
57 * This method only loads classes that exist in the PHP_CodeSniffer namespace.
58 * All other classes are ignored and loaded by subsequent autoloaders.
59 *
60 * @param string $class The name of the class to load.
61 *
62 * @return bool
63 */
64 public static function load($class)
65 {
66 // Include the composer autoloader if there is one, but re-register it
67 // so this autoloader runs before the composer one as we need to include
68 // all files so we can figure out what the class/interface/trait name is.
69 if (self::$composerAutoloader === null) {
70 // Make sure we don't try to load any of Composer's classes
71 // while the autoloader is being setup.
72 if (strpos($class, 'Composer\\') === 0) {
73 return;
74 }
75
76 if (strpos(__DIR__, 'phar://') !== 0
77 && file_exists(__DIR__.'/../../autoload.php') === true
78 ) {
79 self::$composerAutoloader = include __DIR__.'/../../autoload.php';
80 if (self::$composerAutoloader instanceof \Composer\Autoload\ClassLoader) {
81 self::$composerAutoloader->unregister();
82 self::$composerAutoloader->register();
83 } else {
84 // Something went wrong, so keep going without the autoloader
85 // although namespaced sniffs might error.
86 self::$composerAutoloader = false;
87 }
88 } else {
89 self::$composerAutoloader = false;
90 }
91 }//end if
92
93 $ds = DIRECTORY_SEPARATOR;
94 $path = false;
95
96 if (substr($class, 0, 16) === 'PHP_CodeSniffer\\') {
97 if (substr($class, 0, 22) === 'PHP_CodeSniffer\Tests\\') {
98 $isInstalled = !is_dir(__DIR__.$ds.'tests');
99 if ($isInstalled === false) {
100 $path = __DIR__.$ds.'tests';
101 } else {
102 $path = '@test_dir@'.$ds.'PHP_CodeSniffer'.$ds.'CodeSniffer';
103 }
104
105 $path .= $ds.substr(str_replace('\\', $ds, $class), 22).'.php';
106 } else {
107 $path = __DIR__.$ds.'src'.$ds.substr(str_replace('\\', $ds, $class), 16).'.php';
108 }
109 }
110
111 // See if the composer autoloader knows where the class is.
112 if ($path === false && self::$composerAutoloader !== false) {
113 $path = self::$composerAutoloader->findFile($class);
114 }
115
116 // See if the class is inside one of our alternate search paths.
117 if ($path === false) {
118 foreach (self::$searchPaths as $searchPath => $nsPrefix) {
119 $className = $class;
120 if ($nsPrefix !== '' && substr($class, 0, strlen($nsPrefix)) === $nsPrefix) {
121 $className = substr($class, (strlen($nsPrefix) + 1));
122 }
123
124 $path = $searchPath.$ds.str_replace('\\', $ds, $className).'.php';
125 if (is_file($path) === true) {
126 break;
127 }
128
129 $path = false;
130 }
131 }
132
133 if ($path !== false && is_file($path) === true) {
134 self::loadFile($path);
135 return true;
136 }
137
138 return false;
139
140 }//end load()
141
142
143 /**
144 * Includes a file and tracks what class or interface was loaded as a result.
145 *
146 * @param string $path The path of the file to load.
147 *
148 * @return string The fully qualified name of the class in the loaded file.
149 */
150 public static function loadFile($path)
151 {
152 if (strpos(__DIR__, 'phar://') !== 0) {
153 $path = realpath($path);
154 if ($path === false) {
155 return false;
156 }
157 }
158
159 if (isset(self::$loadedClasses[$path]) === true) {
160 return self::$loadedClasses[$path];
161 }
162
163 $classes = get_declared_classes();
164 $interfaces = get_declared_interfaces();
165 $traits = get_declared_traits();
166
167 include $path;
168
169 $className = null;
170 $newClasses = array_reverse(array_diff(get_declared_classes(), $classes));
171 foreach ($newClasses as $name) {
172 if (isset(self::$loadedFiles[$name]) === false) {
173 $className = $name;
174 break;
175 }
176 }
177
178 if ($className === null) {
179 $newClasses = array_reverse(array_diff(get_declared_interfaces(), $interfaces));
180 foreach ($newClasses as $name) {
181 if (isset(self::$loadedFiles[$name]) === false) {
182 $className = $name;
183 break;
184 }
185 }
186 }
187
188 if ($className === null) {
189 $newClasses = array_reverse(array_diff(get_declared_traits(), $traits));
190 foreach ($newClasses as $name) {
191 if (isset(self::$loadedFiles[$name]) === false) {
192 $className = $name;
193 break;
194 }
195 }
196 }
197
198 self::$loadedClasses[$path] = $className;
199 self::$loadedFiles[$className] = $path;
200 return self::$loadedClasses[$path];
201
202 }//end loadFile()
203
204
205 /**
206 * Adds a directory to search during autoloading.
207 *
208 * @param string $path The path to the directory to search.
209 * @param string $nsPrefix The namespace prefix used by files under this path.
210 *
211 * @return void
212 */
213 public static function addSearchPath($path, $nsPrefix='')
214 {
215 self::$searchPaths[$path] = rtrim(trim((string) $nsPrefix), '\\');
216
217 }//end addSearchPath()
218
219
220 /**
221 * Retrieve the namespaces and paths registered by external standards.
222 *
223 * @return array
224 */
225 public static function getSearchPaths()
226 {
227 return self::$searchPaths;
228
229 }//end getSearchPaths()
230
231
232 /**
233 * Gets the class name for the given file path.
234 *
235 * @param string $path The name of the file.
236 *
237 * @throws \Exception If the file path has not been loaded.
238 * @return string
239 */
240 public static function getLoadedClassName($path)
241 {
242 if (isset(self::$loadedClasses[$path]) === false) {
243 throw new \Exception("Cannot get class name for $path; file has not been included");
244 }
245
246 return self::$loadedClasses[$path];
247
248 }//end getLoadedClassName()
249
250
251 /**
252 * Gets the file path for the given class name.
253 *
254 * @param string $class The name of the class.
255 *
256 * @throws \Exception If the class name has not been loaded
257 * @return string
258 */
259 public static function getLoadedFileName($class)
260 {
261 if (isset(self::$loadedFiles[$class]) === false) {
262 throw new \Exception("Cannot get file name for $class; class has not been included");
263 }
264
265 return self::$loadedFiles[$class];
266
267 }//end getLoadedFileName()
268
269
270 /**
271 * Gets the mapping of file names to class names.
272 *
273 * @return array<string, string>
274 */
275 public static function getLoadedClasses()
276 {
277 return self::$loadedClasses;
278
279 }//end getLoadedClasses()
280
281
282 /**
283 * Gets the mapping of class names to file names.
284 *
285 * @return array<string, string>
286 */
287 public static function getLoadedFiles()
288 {
289 return self::$loadedFiles;
290
291 }//end getLoadedFiles()
292
293
294 }//end class
295
296 // Register the autoloader before any existing autoloaders to ensure
297 // it gets a chance to hear about every autoload request, and record
298 // the file and class name for it.
299 spl_autoload_register(__NAMESPACE__.'\Autoload::load', true, true);
300 }//end if