From 9e20ecc6a2aca8379fec3ad95bdcf107d5532bf2 Mon Sep 17 00:00:00 2001 From: Adrian Suter Date: Fri, 3 Jan 2020 12:51:38 +0100 Subject: [PATCH] PSR-12 --- src/AutoloadCollection.php | 62 ++++--- src/ClosureHandler.php | 39 ++-- src/CodeConverter.php | 70 +++++--- src/FileStreamWrapper.php | 296 ++++++++++++++++++------------- src/Override.php | 99 ++++++----- tests/AutoloadCollectionTest.php | 7 +- tests/ClosureHandlerTest.php | 16 +- tests/OverrideTest.php | 3 +- 8 files changed, 354 insertions(+), 238 deletions(-) diff --git a/src/AutoloadCollection.php b/src/AutoloadCollection.php index 0c00897..291dddb 100644 --- a/src/AutoloadCollection.php +++ b/src/AutoloadCollection.php @@ -9,61 +9,67 @@ namespace AdrianSuter\Autoload\Override; +use function array_keys; +use function file_exists; +use function glob; +use function is_dir; +use function realpath; + +/** + * @package AdrianSuter\Autoload\Override + */ class AutoloadCollection { /** - * @var bool[] + * @var bool[] The keys of this associative array are the file paths. */ - private $paths = []; + private $filePaths = []; /** - * @param string $path + * Add a file to the autoload collection. + * + * This method would ignore the file if it could not be found. + * + * @param string $path The path to the file. */ public function addFile(string $path): void { - $path = \realpath($path); - if ($path !== false) { - $this->paths[$path] = true; - } - } - - /** - * @param string[] $directories - */ - public function addDirectories(array $directories): void - { - foreach ($directories as $directory) { - try { - $this->addDirectory($directory); - } catch (\InvalidArgumentException $ignore) { - } + $realpath = realpath($path); + if ($realpath !== false) { + $this->filePaths[$realpath] = true; } } /** - * @param string $directory + * Add a directory, i.e. the php files inside a directory. + * + * This method would ignore the directory if it could not be found. + * + * @param string $directory The directory. */ - public function addDirectory(string $directory) + public function addDirectory(string $directory): void { if ( - !\file_exists($directory) || - !\is_dir($directory) || - false === ($directory = \realpath($directory)) + !file_exists($directory) || + !is_dir($directory) || + false === ($directory = realpath($directory)) ) { - throw new \InvalidArgumentException('Directory could not be found.'); + return; } - $files = \glob($directory . '/*.php'); + $files = glob($directory . '/*.php'); foreach ($files as $file) { $this->addFile($file); } } /** - * @return string[] + * Get the file paths. + * + * @return string[] The file paths. */ public function getFilePaths(): array { - return array_keys($this->paths); + return array_keys($this->filePaths); } } diff --git a/src/ClosureHandler.php b/src/ClosureHandler.php index a664797..9fcd1af 100644 --- a/src/ClosureHandler.php +++ b/src/ClosureHandler.php @@ -12,20 +12,30 @@ use Closure; use RuntimeException; +use function call_user_func_array; +use function sprintf; + +/** + * The ClosureHandler is a Singleton class to handle overrides defined as closures. + * + * @package AdrianSuter\Autoload\Override + */ class ClosureHandler { /** - * @var self + * @var self The singleton instance. */ private static $instance; /** - * @var Closure[] + * @var Closure[] A list of closures. */ private $closures = []; /** - * @return self + * Get the singleton instance. + * + * @return self The ClosureHandler. */ public static function getInstance(): self { @@ -37,28 +47,35 @@ public static function getInstance(): self } /** - * @param string $name - * @param Closure $closure + * Add a closure. + * + * This method would overwrite any previously defined closure with the same name. + * + * @param string $name The closure name. + * @param Closure $closure The closure. */ - function addClosure(string $name, Closure $closure): void + public function addClosure(string $name, Closure $closure): void { $this->closures[$name] = $closure; } /** - * @param string $name - * @param array $arguments + * Magic call. + * + * @param string $name The method name. + * @param array $arguments The method arguments. * * @return mixed */ public function __call(string $name, array $arguments) { if (isset($this->closures[$name])) { - return \call_user_func_array( - $this->closures[$name], $arguments + return call_user_func_array( + $this->closures[$name], + $arguments ); } - throw new RuntimeException(\sprintf('Closure Override "%s" could not be found.', $name)); + throw new RuntimeException(sprintf('Closure Override "%s" could not be found.', $name)); } } diff --git a/src/CodeConverter.php b/src/CodeConverter.php index 0ff9a6c..7ecb399 100644 --- a/src/CodeConverter.php +++ b/src/CodeConverter.php @@ -21,40 +21,51 @@ use PhpParser\Parser\Php7; use PhpParser\PrettyPrinter\Standard; +use function array_keys; +use function array_values; +use function md5; +use function str_replace; +use function uniqid; + +/** + * @package AdrianSuter\Autoload\Override + */ class CodeConverter { + private const ATTR_RESOLVED_NAME = 'resolvedName'; + /** - * @var Parser + * @var Parser The PHP Parser. */ protected $parser; /** - * @var Lexer + * @var Lexer The PHP Lexer. */ protected $lexer; /** - * @var NodeTraverser + * @var NodeTraverser The PHP Node Traverser. */ protected $traverser; /** - * @var Standard + * @var Standard The PHP Printer. */ protected $printer; /** - * @var NodeFinder + * @var NodeFinder The PHP Node Finder. */ protected $nodeFinder; /** - * @param Lexer|null $lexer The lexer. - * @param Parser|null $parser The parser. - * @param NodeTraverser|null $traverser The traverser - make sure that the traverser has a CloningVisitor and a - * NameResolver visitor. - * @param Standard|null $printer The printer. - * @param NodeFinder|null $nodeFinder The node finder. + * @param Lexer|null $lexer The PHP Lexer. + * @param Parser|null $parser The PHP Parser. + * @param NodeTraverser|null $traverser The PHP Node Traverser - make sure that the traverser has a CloningVisitor + * and a NameResolver visitor. + * @param Standard|null $printer The PHP Printer. + * @param NodeFinder|null $nodeFinder The PHP Node Finder. */ public function __construct( ?Lexer $lexer = null, @@ -63,9 +74,11 @@ public function __construct( ?Standard $printer = null, ?NodeFinder $nodeFinder = null ) { - $this->lexer = $lexer ?? new Emulative([ - 'usedAttributes' => ['comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos'], - ]); + $this->lexer = $lexer ?? new Emulative( + [ + 'usedAttributes' => ['comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos'], + ] + ); $this->parser = $parser ?? new Php7($this->lexer); @@ -82,10 +95,10 @@ public function __construct( } /** - * Convert the given code. + * Convert the given source code. * - * @param string $code - * @param array $functionCallMappings + * @param string $code The source code. + * @param array $functionCallMappings The function call mappings. * * @return string */ @@ -100,21 +113,26 @@ public function convert(string $code, array $functionCallMappings): string $funcCalls = $this->nodeFinder->findInstanceOf($newStmts, FuncCall::class); foreach ($funcCalls as $funcCall) { /** @var FuncCall $funcCall */ - if ($funcCall->name->hasAttribute('resolvedName')) { - /** @var FullyQualified $resolvedName */ - $resolvedName = $funcCall->name->getAttribute('resolvedName'); - $resolvedNameCode = $resolvedName->toCodeString(); + if (!$funcCall->name->hasAttribute(self::ATTR_RESOLVED_NAME)) { + continue; + } + + /** @var FullyQualified $resolvedName */ + $resolvedName = $funcCall->name->getAttribute(self::ATTR_RESOLVED_NAME); - if (isset($functionCallMappings[$resolvedNameCode])) { - $k = uniqid(md5($resolvedNameCode), true); - $overridePlaceholders[$k] = $functionCallMappings[$resolvedNameCode]; + $resolvedNameCode = $resolvedName->toCodeString(); + if (isset($functionCallMappings[$resolvedNameCode])) { + $k = uniqid(md5($resolvedNameCode), true); + $overridePlaceholders[$k] = $functionCallMappings[$resolvedNameCode]; - $funcCall->name = new FullyQualified($k); - } + $funcCall->name = new FullyQualified($k); } } $code = $this->printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); + if (empty($overridePlaceholders)) { + return $code; + } return str_replace(array_keys($overridePlaceholders), array_values($overridePlaceholders), $code); } diff --git a/src/FileStreamWrapper.php b/src/FileStreamWrapper.php index 7578d54..1703854 100644 --- a/src/FileStreamWrapper.php +++ b/src/FileStreamWrapper.php @@ -9,6 +9,39 @@ namespace AdrianSuter\Autoload\Override; +use function chgrp; +use function chmod; +use function chown; +use function closedir; +use function fclose; +use function feof; +use function fflush; +use function fgets; +use function file_get_contents; +use function fopen; +use function fseek; +use function fstat; +use function ftruncate; +use function fwrite; +use function is_resource; +use function is_string; +use function lstat; +use function mkdir; +use function opendir; +use function readdir; +use function rename; +use function rewinddir; +use function rmdir; +use function stat; +use function stream_set_blocking; +use function stream_set_timeout; +use function stream_set_write_buffer; +use function stream_wrapper_register; +use function stream_wrapper_restore; +use function stream_wrapper_unregister; +use function touch; +use function unlink; + class FileStreamWrapper { /** @@ -28,12 +61,12 @@ class FileStreamWrapper */ public function dir_closedir(): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - \closedir($this->resource); + closedir($this->resource); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return true; } @@ -42,39 +75,41 @@ public function dir_closedir(): bool * Open directory handle. * * @param string $path - * @param int $options + * @param int $options * * @return bool + * @noinspection PhpUnusedParameterInspection */ public function dir_opendir(string $path, int $options): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - if (\is_resource($this->context)) { - $this->resource = \opendir($path, $this->context); + if (is_resource($this->context)) { + $this->resource = opendir($path, $this->context); } else { - $this->resource = \opendir($path); + $this->resource = opendir($path); } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); - return \is_resource($this->resource); + return is_resource($this->resource); } /** * Read entry from directory handle. * * @return false|string + * @noinspection PhpUnused */ public function dir_readdir() { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \readdir($this->resource); + $r = readdir($this->resource); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -83,15 +118,16 @@ public function dir_readdir() * Rewind directory handle. * * @return bool + * @noinspection PhpUnused */ public function dir_rewinddir(): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - \rewinddir($this->resource); + rewinddir($this->resource); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return true; } @@ -100,24 +136,24 @@ public function dir_rewinddir(): bool * Create a directory. * * @param string $path - * @param int $mode - * @param int $options + * @param int $mode + * @param int $options * * @return bool */ public function mkdir(string $path, int $mode, int $options): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); $recursive = $options & STREAM_MKDIR_RECURSIVE ? true : false; - if (\is_resource($this->context)) { - $r = \mkdir($path, $mode, $recursive, $this->context); + if (is_resource($this->context)) { + $r = mkdir($path, $mode, $recursive, $this->context); } else { - $r = \mkdir($path, $mode, $recursive); + $r = mkdir($path, $mode, $recursive); } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -132,16 +168,16 @@ public function mkdir(string $path, int $mode, int $options): bool */ public function rename(string $path_from, string $path_to): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - if (\is_resource($this->context)) { - $r = \rename($path_from, $path_to, $this->context); + if (is_resource($this->context)) { + $r = rename($path_from, $path_to, $this->context); } else { - $r = \rename($path_from, $path_to); + $r = rename($path_from, $path_to); } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -150,22 +186,23 @@ public function rename(string $path_from, string $path_to): bool * Remove a directory. * * @param string $path - * @param int $options + * @param int $options * * @return bool + * @noinspection PhpUnusedParameterInspection */ public function rmdir(string $path, int $options): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - if (\is_resource($this->context)) { - $r = \rmdir($path, $this->context); + if (is_resource($this->context)) { + $r = rmdir($path, $this->context); } else { - $r = \rmdir($path); + $r = rmdir($path); } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -176,10 +213,11 @@ public function rmdir(string $path, int $options): bool * @param int $cast_as * * @return false|resource + * @noinspection PhpUnusedParameterInspection */ public function stream_cast(int $cast_as) { - if (\is_resource($this->resource)) { + if (is_resource($this->resource)) { return $this->resource; } @@ -188,30 +226,32 @@ public function stream_cast(int $cast_as) /** * Close a resource. + * @noinspection PhpUnused */ public function stream_close(): void { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - \fclose($this->resource); + fclose($this->resource); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); } /** * Test for end-of-file on a file pointer. * * @return bool + * @noinspection PhpUnused */ public function stream_eof(): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \feof($this->resource); + $r = feof($this->resource); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -220,15 +260,16 @@ public function stream_eof(): bool * Flush the output * * @return bool + * @noinspection PhpUnused */ public function stream_flush(): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \fflush($this->resource); + $r = fflush($this->resource); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -239,6 +280,8 @@ public function stream_flush(): bool * @param int $operation * * @return bool + * @noinspection PhpUnused + * @noinspection PhpUnusedParameterInspection */ public function stream_lock(int $operation): bool { @@ -249,42 +292,43 @@ public function stream_lock(int $operation): bool * Change stream metadata. * * @param string $path - * @param int $option - * @param mixed $value + * @param int $option + * @param mixed $value * * @return bool + * @noinspection PhpUnused */ public function stream_metadata(string $path, int $option, $value): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); $r = false; switch ($option) { case STREAM_META_TOUCH: if (!isset($value[0]) || $value[0] === null) { - $r = \touch($path); + $r = touch($path); } else { - $r = \touch($path, $value[0], $value[1]); + $r = touch($path, $value[0], $value[1]); } break; case STREAM_META_OWNER_NAME: case STREAM_META_OWNER: - $r = \chown($path, $value); + $r = chown($path, $value); break; case STREAM_META_GROUP_NAME: case STREAM_META_GROUP: - $r = \chgrp($path, $value); + $r = chgrp($path, $value); break; case STREAM_META_ACCESS: - $r = \chmod($path, $value); + $r = chmod($path, $value); break; } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -292,19 +336,21 @@ public function stream_metadata(string $path, int $option, $value): bool /** * Open file or URL. * - * @param string $path - * @param string $mode - * @param int $options + * @param string $path + * @param string $mode + * @param int $options * @param string|null $opened_path * * @return bool + * @noinspection PhpUnused + * @noinspection PhpUnusedParameterInspection */ public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); $usePath = $options & STREAM_USE_PATH ? true : false; - $reportErrors = $options & STREAM_REPORT_ERRORS ? true : false; + // $reportErrors = $options & STREAM_REPORT_ERRORS ? true : false; // TODO Implement error reporting as well as opened_path. @@ -312,23 +358,23 @@ public function stream_open(string $path, string $mode, int $options, ?string &$ // Replace the global function calls into local function calls. if (!empty($functionCallMappings)) { - $source = \file_get_contents($path, $usePath); + $source = file_get_contents($path, $usePath); $source = Override::getCodeConverter()->convert($source, $functionCallMappings); - $this->resource = \fopen('php://temp', 'w+'); - \fwrite($this->resource, $source); - \fseek($this->resource, 0); - } elseif (\is_resource($this->context)) { - $this->resource = \fopen($path, $mode, $usePath, $this->context); + $this->resource = fopen('php://temp', 'w+'); + fwrite($this->resource, $source); + fseek($this->resource, 0); + } elseif (is_resource($this->context)) { + $this->resource = fopen($path, $mode, $usePath, $this->context); } else { - $this->resource = \fopen($path, $mode, $usePath); + $this->resource = fopen($path, $mode, $usePath); } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); - return \is_resource($this->resource) ? true : false; + return is_resource($this->resource) ? true : false; } /** @@ -337,17 +383,18 @@ public function stream_open(string $path, string $mode, int $options, ?string &$ * @param int $count * * @return string + * @noinspection PhpUnused */ public function stream_read(int $count): string { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \fgets($this->resource, $count); + $r = fgets($this->resource, $count); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); - if (!\is_string($r)) { + if (!is_string($r)) { return ''; } @@ -361,15 +408,16 @@ public function stream_read(int $count): string * @param int $whence * * @return bool + * @noinspection PhpUnused */ public function stream_seek(int $offset, int $whence = SEEK_SET): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \fseek($this->resource, $offset, $whence); + $r = fseek($this->resource, $offset, $whence); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r < 0 ? false : true; } @@ -382,36 +430,37 @@ public function stream_seek(int $offset, int $whence = SEEK_SET): bool * @param int $arg2 * * @return bool|int + * @noinspection PhpUnused */ public function stream_set_option(int $option, int $arg1, ?int $arg2) { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); $r = false; switch ($option) { case STREAM_OPTION_BLOCKING: - $r = \stream_set_blocking($this->resource, $arg1 ? true : false); + $r = stream_set_blocking($this->resource, $arg1 ? true : false); break; case STREAM_OPTION_READ_TIMEOUT: - $r = \stream_set_timeout($this->resource, $arg1, $arg2); + $r = stream_set_timeout($this->resource, $arg1, $arg2); break; case STREAM_OPTION_WRITE_BUFFER: switch ($arg1) { case STREAM_BUFFER_NONE: - $r = \stream_set_write_buffer($this->resource, 0); + $r = stream_set_write_buffer($this->resource, 0); break; case STREAM_BUFFER_FULL: - $r = \stream_set_write_buffer($this->resource, $arg2); + $r = stream_set_write_buffer($this->resource, $arg2); break; } break; } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -420,15 +469,16 @@ public function stream_set_option(int $option, int $arg1, ?int $arg2) * Retrieve information about a file resource. * * @return array + * @noinspection PhpUnused */ public function stream_stat(): array { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \fstat($this->resource); + $r = fstat($this->resource); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -437,15 +487,16 @@ public function stream_stat(): array * Retrieve the current position of a stream. * * @return int + * @noinspection PhpUnused */ public function stream_tell(): int { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \fseek($this->resource, 0, SEEK_CUR); + $r = fseek($this->resource, 0, SEEK_CUR); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -456,15 +507,16 @@ public function stream_tell(): int * @param int $new_size * * @return bool + * @noinspection PhpUnused */ public function stream_truncate(int $new_size): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \ftruncate($this->resource, $new_size); + $r = ftruncate($this->resource, $new_size); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -475,15 +527,16 @@ public function stream_truncate(int $new_size): bool * @param string $data * * @return int|false + * @noinspection PhpUnused */ public function stream_write(string $data) { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \fwrite($this->resource, $data); + $r = fwrite($this->resource, $data); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -497,12 +550,12 @@ public function stream_write(string $data) */ public function unlink(string $path): bool { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); - $r = \unlink($path); + $r = unlink($path); - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } @@ -511,25 +564,26 @@ public function unlink(string $path): bool * Retrieve information about a file. * * @param string $path - * @param int $flags + * @param int $flags * * @return array|false + * @noinspection PhpUnused */ public function url_stat(string $path, int $flags) { - \stream_wrapper_restore('file'); + stream_wrapper_restore('file'); $urlStatLink = $flags & STREAM_URL_STAT_LINK ? true : false; $urlStatQuiet = $flags & STREAM_URL_STAT_QUIET ? true : false; if ($urlStatLink) { - $r = $urlStatQuiet ? @\lstat($path) : \lstat($path); + $r = $urlStatQuiet ? @lstat($path) : lstat($path); } else { - $r = $urlStatQuiet ? @\stat($path) : \stat($path); + $r = $urlStatQuiet ? @stat($path) : stat($path); } - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', self::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', self::class); return $r; } diff --git a/src/Override.php b/src/Override.php index 2d03512..6ffc7c0 100644 --- a/src/Override.php +++ b/src/Override.php @@ -13,6 +13,27 @@ use Composer\Autoload\ClassLoader; use RuntimeException; +use function array_merge; +use function array_pop; +use function array_unshift; +use function class_exists; +use function clearstatcache; +use function dirname; +use function explode; +use function file_exists; +use function implode; +use function is_dir; +use function is_numeric; +use function is_string; +use function realpath; +use function spl_object_hash; +use function stream_wrapper_register; +use function stream_wrapper_restore; +use function stream_wrapper_unregister; +use function strlen; +use function substr; +use function trim; + class Override { /** @@ -52,9 +73,9 @@ public static function getCodeConverter(): CodeConverter } /** - * @param ClassLoader $classLoader + * @param ClassLoader $classLoader * @param string[]|Closure[] $functionCallMappings - * @param string $namespace + * @param string $namespace */ public static function apply( ClassLoader $classLoader, @@ -66,7 +87,7 @@ public static function apply( } // Make sure that the stream wrapper class is loaded. - if (!\class_exists(FileStreamWrapper::class)) { + if (!class_exists(FileStreamWrapper::class)) { $classLoader->loadClass(FileStreamWrapper::class); } @@ -80,46 +101,46 @@ public static function apply( foreach ($functionCallMappings as $fqn => $mappings) { $fqnFunctionCallMappings = self::buildMappings($mappings, $namespace); - if (\substr($fqn, -1, 1) === '\\') { + if (substr($fqn, -1, 1) === '\\') { // The given fqn is a namespace. $prefixesPsr4 = $classLoader->getPrefixesPsr4(); $handled = []; $popped = []; - $parts = \explode('\\', \trim($fqn, '\\')); + $parts = explode('\\', trim($fqn, '\\')); while (!empty($parts)) { - $glued = \implode('\\', $parts) . '\\'; + $glued = implode('\\', $parts) . '\\'; if (isset($prefixesPsr4[$glued])) { - $subDir = \implode('/', $popped); + $subDir = implode('/', $popped); foreach ($prefixesPsr4[$glued] as $directory) { - $dir = \realpath($directory . '/' . $subDir); + $dir = realpath($directory . '/' . $subDir); if ($dir === false) { continue; } - if (\is_dir($dir) && !isset($handled[$dir])) { + if (is_dir($dir) && !isset($handled[$dir])) { $handled[$dir] = true; - //echo $dir . PHP_EOL; + self::addNamespaceData([$dir], $fqnFunctionCallMappings); - $autoloadCollection->addDirectories([$dir]); + $autoloadCollection->addDirectory($dir); } } } - \array_unshift($popped, \array_pop($parts)); + array_unshift($popped, array_pop($parts)); } foreach ($classLoader->getClassMap() as $classMapFqn => $classMapPath) { - if (\substr($classMapFqn, 0, \strlen($fqn)) === $fqn) { - $p = \realpath($classMapPath); + if (substr($classMapFqn, 0, strlen($fqn)) === $fqn) { + $p = realpath($classMapPath); if ($p === false) { continue; } if (isset(self::$fileFunctionCallMappings[$p])) { - self::$fileFunctionCallMappings[$p] = \array_merge( + self::$fileFunctionCallMappings[$p] = array_merge( $fqnFunctionCallMappings, self::$fileFunctionCallMappings[$p] ); @@ -130,9 +151,9 @@ public static function apply( } } - foreach ($classLoader->getFallbackDirsPsr4() as $fallbackDirPsr4) { - // TODO: Handle this case. - } + //foreach ($classLoader->getFallbackDirsPsr4() as $fallbackDirPsr4) { + // TODO: Handle this case. + //} continue; } @@ -142,7 +163,7 @@ public static function apply( continue; } - $path = \realpath($filePath); + $path = realpath($filePath); if ($path === false) { // The file could not be found. continue; @@ -153,20 +174,20 @@ public static function apply( } // Load the classes that are affected by the FQFC-override converter. - \stream_wrapper_unregister('file'); - \stream_wrapper_register('file', FileStreamWrapper::class); + stream_wrapper_unregister('file'); + stream_wrapper_register('file', FileStreamWrapper::class); foreach ($autoloadCollection->getFilePaths() as $file) { /** @noinspection PhpIncludeInspection */ include_once $file; } - \stream_wrapper_restore('file'); - \clearstatcache(); + stream_wrapper_restore('file'); + clearstatcache(); } /** * @param string[]|Closure[] $mappings - * @param string $namespace + * @param string $namespace * * @return array */ @@ -174,17 +195,15 @@ private static function buildMappings(array $mappings, string $namespace): array { $fcMappings = []; foreach ($mappings as $key => $val) { - if (\is_numeric($key)) { + if (is_numeric($key)) { $fcMappings['\\' . $val] = $namespace . '\\' . $val; - } else { - if (\is_string($val)) { - $fcMappings['\\' . $key] = $val . '\\' . $key; - } elseif ($val instanceof Closure) { - $name = $key . '_' . \spl_object_hash($val); - ClosureHandler::getInstance()->addClosure($name, $val); + } elseif (is_string($val)) { + $fcMappings['\\' . $key] = $val . '\\' . $key; + } elseif ($val instanceof Closure) { + $name = $key . '_' . spl_object_hash($val); + ClosureHandler::getInstance()->addClosure($name, $val); - $fcMappings['\\' . $key] = ClosureHandler::class . '::getInstance()->' . $name; - } + $fcMappings['\\' . $key] = ClosureHandler::class . '::getInstance()->' . $name; } } @@ -194,13 +213,13 @@ private static function buildMappings(array $mappings, string $namespace): array private static function addNamespaceData(array $directories, array $functionMappings): void { foreach ($directories as $dir) { - if (!\file_exists($dir)) { + if (!file_exists($dir)) { continue; } - $dir = \realpath($dir); + $dir = realpath($dir); if (isset(self::$dirFunctionCallMappings[$dir])) { - self::$dirFunctionCallMappings[$dir] = \array_merge( + self::$dirFunctionCallMappings[$dir] = array_merge( self::$dirFunctionCallMappings[$dir], $functionMappings ); @@ -217,16 +236,16 @@ private static function addNamespaceData(array $directories, array $functionMapp */ public static function getFunctionMappings(string $filePath): array { - $filePath = \realpath($filePath); - $dirPath = \dirname($filePath); + $filePath = realpath($filePath); + $dirPath = dirname($filePath); $mappings = []; if (isset(self::$dirFunctionCallMappings[$dirPath])) { - $mappings = \array_merge($mappings, self::$dirFunctionCallMappings[$dirPath]); + $mappings = array_merge($mappings, self::$dirFunctionCallMappings[$dirPath]); } if (isset(self::$fileFunctionCallMappings[$filePath])) { - $mappings = \array_merge($mappings, self::$fileFunctionCallMappings[$filePath]); + $mappings = array_merge($mappings, self::$fileFunctionCallMappings[$filePath]); } return $mappings; diff --git a/tests/AutoloadCollectionTest.php b/tests/AutoloadCollectionTest.php index 9df3622..f7b8579 100644 --- a/tests/AutoloadCollectionTest.php +++ b/tests/AutoloadCollectionTest.php @@ -12,12 +12,11 @@ class AutoloadCollectionTest extends TestCase { - /** - * @expectedException InvalidArgumentException - */ - public function testAddDirectories() + public function testAddDirectory() { $autoloadCollection = new AutoloadCollection(); $autoloadCollection->addDirectory(__DIR__ . '/not-existent'); + + $this->assertTrue(true); } } diff --git a/tests/ClosureHandlerTest.php b/tests/ClosureHandlerTest.php index 6963197..26be267 100644 --- a/tests/ClosureHandlerTest.php +++ b/tests/ClosureHandlerTest.php @@ -15,20 +15,22 @@ final class ClosureHandlerTest extends TestCase public function testDefault() { $closureHandler = ClosureHandler::getInstance(); - $closureHandler->addClosure('test', function (): int { - return 42; - }); + $closureHandler->addClosure( + 'test', + function (): int { + return 42; + } + ); /** @noinspection PhpUndefinedMethodInspection */ $this->assertEquals(42, $closureHandler->test()); } - /** - * @expectedException RuntimeException - * @expectedExceptionMessage Closure Override "thisIsNotDefined" could not be found. - */ public function testUndefinedClosure() { + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage('Closure Override "thisIsNotDefined" could not be found.'); + $closureHandler = ClosureHandler::getInstance(); /** @noinspection PhpUndefinedMethodInspection */ diff --git a/tests/OverrideTest.php b/tests/OverrideTest.php index d8119d6..3ee847f 100644 --- a/tests/OverrideTest.php +++ b/tests/OverrideTest.php @@ -11,6 +11,7 @@ use AdrianSuter\Autoload\Override\Override; use Composer\Autoload\ClassLoader; use PHPUnit\Framework\TestCase; +use Prophecy\Prophecy\MethodProphecy; /** * @runTestsInSeparateProcesses @@ -40,7 +41,7 @@ public function testApplyApcu() { $classLoaderProphecy = $this->prophesize(ClassLoader::class); - $getApcuPrefixMethodProphecy = new \Prophecy\Prophecy\MethodProphecy($classLoaderProphecy, 'getApcuPrefix', []); + $getApcuPrefixMethodProphecy = new MethodProphecy($classLoaderProphecy, 'getApcuPrefix', []); $getApcuPrefixMethodProphecy->willReturn('a'); $classLoaderProphecy->addMethodProphecy($getApcuPrefixMethodProphecy);