|
22 | 22 | use PHPStan\Type\FileTypeMapper;
|
23 | 23 | use PHPStan\Type\Type;
|
24 | 24 | use PHPStan\Type\VerbosityLevel;
|
| 25 | +use Symfony\Component\Finder\Finder; |
25 | 26 | use function array_map;
|
26 | 27 | use function array_merge;
|
27 | 28 | use function count;
|
| 29 | +use function fclose; |
| 30 | +use function fgets; |
| 31 | +use function fopen; |
28 | 32 | use function in_array;
|
| 33 | +use function is_dir; |
29 | 34 | use function is_string;
|
| 35 | +use function preg_match; |
30 | 36 | use function sprintf;
|
31 | 37 | use function stripos;
|
| 38 | +use function strpos; |
32 | 39 | use function strtolower;
|
| 40 | +use function version_compare; |
| 41 | +use const PHP_VERSION; |
33 | 42 |
|
34 | 43 | /** @api */
|
35 | 44 | abstract class TypeInferenceTestCase extends PHPStanTestCase
|
@@ -240,6 +249,64 @@ public static function gatherAssertTypes(string $file): array
|
240 | 249 | return $asserts;
|
241 | 250 | }
|
242 | 251 |
|
| 252 | + /** |
| 253 | + * @api |
| 254 | + * @return array<string, mixed[]> |
| 255 | + */ |
| 256 | + public static function gatherAssertTypesFromDirectory(string $directory): array |
| 257 | + { |
| 258 | + if (!is_dir($directory)) { |
| 259 | + self::fail(sprintf('Directory %s does not exist.', $directory)); |
| 260 | + } |
| 261 | + |
| 262 | + $finder = new Finder(); |
| 263 | + $finder->followLinks(); |
| 264 | + $asserts = []; |
| 265 | + foreach ($finder->files()->name('*.php')->in($directory) as $fileInfo) { |
| 266 | + $path = $fileInfo->getPathname(); |
| 267 | + if (self::isFileLintSkipped($path)) { |
| 268 | + continue; |
| 269 | + } |
| 270 | + foreach (self::gatherAssertTypes($path) as $key => $assert) { |
| 271 | + $asserts[$key] = $assert; |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + return $asserts; |
| 276 | + } |
| 277 | + |
| 278 | + /** |
| 279 | + * From https://github.com/php-parallel-lint/PHP-Parallel-Lint/blob/0c2706086ac36dce31967cb36062ff8915fe03f7/bin/skip-linting.php |
| 280 | + * |
| 281 | + * Copyright (c) 2012, Jakub Onderka |
| 282 | + */ |
| 283 | + private static function isFileLintSkipped(string $file): bool |
| 284 | + { |
| 285 | + $f = @fopen($file, 'r'); |
| 286 | + if ($f !== false) { |
| 287 | + $firstLine = fgets($f); |
| 288 | + if ($firstLine === false) { |
| 289 | + return false; |
| 290 | + } |
| 291 | + |
| 292 | + // ignore shebang line |
| 293 | + if (strpos($firstLine, '#!') === 0) { |
| 294 | + $firstLine = fgets($f); |
| 295 | + if ($firstLine === false) { |
| 296 | + return false; |
| 297 | + } |
| 298 | + } |
| 299 | + |
| 300 | + @fclose($f); |
| 301 | + |
| 302 | + if (preg_match('~<?php\\s*\\/\\/\s*lint\s*([^\d\s]+)\s*([^\s]+)\s*~i', $firstLine, $m) === 1) { |
| 303 | + return version_compare(PHP_VERSION, $m[2], $m[1]) === false; |
| 304 | + } |
| 305 | + } |
| 306 | + |
| 307 | + return false; |
| 308 | + } |
| 309 | + |
243 | 310 | /** @return string[] */
|
244 | 311 | protected static function getAdditionalAnalysedFiles(): array
|
245 | 312 | {
|
|
0 commit comments