diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 86d922c33302..65c535e8611e 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -21,7 +21,7 @@ use Config\Autoload; use Config\Kint as KintConfig; use Config\Modules; -use Kint; +use Kint\Kint; use Kint\Renderer\CliRenderer; use Kint\Renderer\RichRenderer; @@ -67,21 +67,21 @@ class Autoloader /** * Stores namespaces as key, and path as values. * - * @var array> + * @var array> */ protected $prefixes = []; /** * Stores class name as key, and path as values. * - * @var array + * @var array */ protected $classmap = []; /** * Stores files as a list. * - * @var list + * @var list */ protected $files = []; @@ -89,7 +89,7 @@ class Autoloader * Stores helper list. * Always load the URL helper, it should be used in most apps. * - * @var list + * @var list */ protected $helpers = ['url']; @@ -147,36 +147,35 @@ private function loadComposerAutoloader(Modules $modules): void // Should we load through Composer's namespaces, also? if ($modules->discoverInComposer) { - // @phpstan-ignore-next-line - $this->loadComposerNamespaces($composer, $modules->composerPackages ?? []); + $composerPackages = $modules->composerPackages; + $this->loadComposerNamespaces($composer, $composerPackages ?? []); } unset($composer); } /** - * Register the loader with the SPL autoloader stack. + * Register the loader with the SPL autoloader stack + * in the following order: + * + * 1. Classmap loader + * 2. PSR-4 autoloader + * 3. Non-class files * * @return void */ public function register() { - // Register classmap loader for the files in our class map. spl_autoload_register($this->loadClassmap(...), true); - - // Register the PSR-4 autoloader. spl_autoload_register($this->loadClass(...), true); - // Load our non-class files foreach ($this->files as $file) { $this->includeFile($file); } } /** - * Unregister autoloader. - * - * This method is for testing. + * Unregisters the autoloader from the SPL autoload stack. */ public function unregister(): void { @@ -187,7 +186,7 @@ public function unregister(): void /** * Registers namespaces with the autoloader. * - * @param array|string>|string $namespace + * @param array|non-empty-string>|non-empty-string $namespace * * @return $this */ @@ -219,7 +218,7 @@ public function addNamespace($namespace, ?string $path = null) * * If a prefix param is set, returns only paths to the given prefix. * - * @return ($prefix is null ? array> : list) + * @return ($prefix is null ? array> : list) */ public function getNamespace(?string $prefix = null) { @@ -247,6 +246,8 @@ public function removeNamespace(string $namespace) /** * Load a class using available class mapping. * + * @param class-string $class The fully qualified class name. + * * @internal For `spl_autoload_register` use. */ public function loadClassmap(string $class): void @@ -261,9 +262,9 @@ public function loadClassmap(string $class): void /** * Loads the class file for a given class name. * - * @internal For `spl_autoload_register` use. + * @param class-string $class The fully qualified class name. * - * @param string $class The fully qualified class name. + * @internal For `spl_autoload_register` use. */ public function loadClass(string $class): void { @@ -273,9 +274,9 @@ public function loadClass(string $class): void /** * Loads the class file for a given class name. * - * @param string $class The fully-qualified class name + * @param class-string $class The fully qualified class name. * - * @return false|string The mapped file name on success, or boolean false on fail + * @return false|non-empty-string The mapped file name on success, or boolean false on fail */ protected function loadInNamespace(string $class) { @@ -293,21 +294,20 @@ protected function loadInNamespace(string $class) $filePath = $directory . $relativeClassPath . '.php'; $filename = $this->includeFile($filePath); - if ($filename) { + if ($filename !== false) { return $filename; } } } } - // never found a mapped file return false; } /** * A central way to include a file. Split out primarily for testing purposes. * - * @return false|string The filename on success, false if the file is not loaded + * @return false|non-empty-string The filename on success, false if the file is not loaded */ protected function includeFile(string $file) { diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index 13ecb817a56c..f67708a4e836 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -44,7 +44,7 @@ public function __construct(Autoloader $autoloader) * Attempts to locate a file by examining the name for a namespace * and looking through the PSR-4 namespaced files that we know about. * - * @param string $file The relative file path or namespaced file to + * @param non-empty-string $file The relative file path or namespaced file to * locate. If not namespaced, search in the app * folder. * @param non-empty-string|null $folder The folder within the namespace that we should @@ -53,7 +53,7 @@ public function __construct(Autoloader $autoloader) * folder. * @param string $ext The file extension the file should have. * - * @return false|string The path to the file, or false if not found. + * @return false|non-empty-string The path to the file, or false if not found. */ public function locateFile(string $file, ?string $folder = null, string $ext = 'php') { @@ -156,9 +156,11 @@ public function getClassname(string $file): string $dlm = false; } - if (($tokens[$i - 2][0] === T_CLASS || (isset($tokens[$i - 2][1]) && $tokens[$i - 2][1] === 'phpclass')) + if ( + ($tokens[$i - 2][0] === T_CLASS || (isset($tokens[$i - 2][1]) && $tokens[$i - 2][1] === 'phpclass')) && $tokens[$i - 1][0] === T_WHITESPACE - && $token[0] === T_STRING) { + && $token[0] === T_STRING + ) { $className = $token[1]; break; } @@ -184,7 +186,7 @@ public function getClassname(string $file): string * 'app/Modules/bar/Config/Routes.php', * ] * - * @return list + * @return list */ public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array { @@ -213,7 +215,6 @@ public function search(string $path, string $ext = 'php', bool $prioritizeApp = $foundPaths = [...$foundPaths, ...$appPaths]; } - // Remove any duplicates return array_values(array_unique($foundPaths)); } @@ -236,13 +237,12 @@ protected function ensureExt(string $path, string $ext): string /** * Return the namespace mappings we know about. * - * @return array> + * @return list */ protected function getNamespaces() { $namespaces = []; - // Save system for last $system = []; foreach ($this->autoloader->getNamespace() as $prefix => $paths) { @@ -263,6 +263,7 @@ protected function getNamespaces() } } + // Save system for last return array_merge($namespaces, $system); } @@ -295,19 +296,17 @@ public function findQualifiedNameFromPath(string $path) ); // Remove the file extension (.php) - /** @var class-string */ + /** @var class-string $className */ $className = mb_substr($className, 0, -4); if (in_array($className, $this->invalidClassnames, true)) { continue; } - // Check if this exists if (class_exists($className)) { return $className; } - // If the class does not exist, it is an invalid classname. $this->invalidClassnames[] = $className; } } @@ -353,11 +352,11 @@ public function listFiles(string $path): array * Scans the provided namespace, returning a list of all files * that are contained within the sub path specified by $path. * - * @return list List of file paths + * @return list List of file paths */ public function listNamespaceFiles(string $prefix, string $path): array { - if ($path === '' || ($prefix === '')) { + if ($path === '' || $prefix === '') { return []; } diff --git a/system/Autoloader/FileLocatorCached.php b/system/Autoloader/FileLocatorCached.php index 8b17399444c6..0aa267b2a84b 100644 --- a/system/Autoloader/FileLocatorCached.php +++ b/system/Autoloader/FileLocatorCached.php @@ -117,7 +117,7 @@ public function getClassname(string $file): string } /** - * @return list + * @return list */ public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array { diff --git a/system/Autoloader/FileLocatorInterface.php b/system/Autoloader/FileLocatorInterface.php index 8f6129abee17..0422ec2519db 100644 --- a/system/Autoloader/FileLocatorInterface.php +++ b/system/Autoloader/FileLocatorInterface.php @@ -23,7 +23,7 @@ interface FileLocatorInterface * Attempts to locate a file by examining the name for a namespace * and looking through the PSR-4 namespaced files that we know about. * - * @param string $file The relative file path or namespaced file to + * @param non-empty-string $file The relative file path or namespaced file to * locate. If not namespaced, search in the app * folder. * @param non-empty-string|null $folder The folder within the namespace that we should @@ -32,12 +32,14 @@ interface FileLocatorInterface * folder. * @param string $ext The file extension the file should have. * - * @return false|string The path to the file, or false if not found. + * @return false|non-empty-string The path to the file, or false if not found. */ public function locateFile(string $file, ?string $folder = null, string $ext = 'php'); /** * Examines a file and returns the fully qualified class name. + * + * @param non-empty-string $file */ public function getClassname(string $file): string; @@ -54,7 +56,7 @@ public function getClassname(string $file): string; * 'app/Modules/bar/Config/Routes.php', * ] * - * @return list + * @return list */ public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array; diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php index af5340400160..cd73356958fe 100644 --- a/tests/system/Autoloader/AutoloaderTest.php +++ b/tests/system/Autoloader/AutoloaderTest.php @@ -394,7 +394,7 @@ public function testAutoloaderLoadsNonClassFiles(): void $this->assertTrue(function_exists('autoload_foo')); $this->assertSame('I am autoloaded by Autoloader through $files!', autoload_foo()); - $this->assertTrue(defined('AUTOLOAD_CONSTANT')); + $this->assertTrue(defined('AUTOLOAD_CONSTANT')); // @phpstan-ignore method.alreadyNarrowedType $this->assertSame('foo', AUTOLOAD_CONSTANT); $loader->unregister(); diff --git a/utils/phpstan-baseline/loader.neon b/utils/phpstan-baseline/loader.neon index 4754c3cd6c9b..00cce6e6c73b 100644 --- a/utils/phpstan-baseline/loader.neon +++ b/utils/phpstan-baseline/loader.neon @@ -1,4 +1,4 @@ -# total 3075 errors +# total 3074 errors includes: - argument.type.neon - assign.propertyType.neon diff --git a/utils/phpstan-baseline/method.alreadyNarrowedType.neon b/utils/phpstan-baseline/method.alreadyNarrowedType.neon index 23132319175b..f980738a073a 100644 --- a/utils/phpstan-baseline/method.alreadyNarrowedType.neon +++ b/utils/phpstan-baseline/method.alreadyNarrowedType.neon @@ -1,4 +1,4 @@ -# total 24 errors +# total 23 errors parameters: ignoreErrors: @@ -7,11 +7,6 @@ parameters: count: 1 path: ../../admin/starter/tests/unit/HealthTest.php - - - message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertTrue\(\) with bool will always evaluate to true\.$#' - count: 1 - path: ../../tests/system/Autoloader/AutoloaderTest.php - - message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertIsBool\(\) with bool will always evaluate to true\.$#' count: 1