diff --git a/build/baseline-8.0.neon b/build/baseline-8.0.neon index 7d6f91d1c8..27631e9a5e 100644 --- a/build/baseline-8.0.neon +++ b/build/baseline-8.0.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Strict comparison using \\=\\=\\= between array and false will always evaluate to false\\.$#" - count: 1 - path: ../src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php - - message: "#^Strict comparison using \\=\\=\\= between array and false will always evaluate to false\\.$#" count: 1 diff --git a/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php b/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php index 38a62770f9..7ca2ab2151 100644 --- a/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php +++ b/src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php @@ -28,9 +28,6 @@ use function interface_exists; use function is_file; use function is_string; -use function restore_error_handler; -use function set_error_handler; -use function spl_autoload_functions; use function strtolower; use function trait_exists; use const PHP_VERSION_ID; @@ -180,8 +177,10 @@ public function locateIdentifier(Reflector $reflector, Identifier $identifier): ); } } + return null; } + [$potentiallyLocatedFile, $className, $startLine] = $locateResult; return $this->findReflection($reflector, $potentiallyLocatedFile, new Identifier($className, $identifier->getType()), $startLine); @@ -259,23 +258,11 @@ public function locateIdentifiersByType(Reflector $reflector, IdentifierType $id } /** - * Attempt to locate a class by name. - * - * If class already exists, simply use internal reflection API to get the - * filename and store it. - * - * If class does not exist, we make an assumption that whatever autoloaders - * that are registered will be loading a file. We then override the file:// - * protocol stream wrapper to "capture" the filename we expect the class to - * be in, and then restore it. Note that class_exists will cause an error - * that it cannot find the file, so we squelch the errors by overriding the - * error handler temporarily. - * * @return array{string, string, int|null}|null */ private function locateClassByName(string $className): ?array { - if (class_exists($className, false) || interface_exists($className, false) || trait_exists($className, false)) { + if (class_exists($className) || interface_exists($className) || trait_exists($className)) { $reflection = new ReflectionClass($className); $filename = $reflection->getFileName(); @@ -290,42 +277,7 @@ private function locateClassByName(string $className): ?array return [$filename, $reflection->getName(), $reflection->getStartLine() !== false ? $reflection->getStartLine() : null]; } - $this->silenceErrors(); - - try { - /** @var array{string, string, null}|null */ - return FileReadTrapStreamWrapper::withStreamWrapperOverride( - static function () use ($className): ?array { - $functions = spl_autoload_functions(); - if ($functions === false) { - return null; - } - - foreach ($functions as $preExistingAutoloader) { - $preExistingAutoloader($className); - - /** - * This static variable is populated by the side-effect of the stream wrapper - * trying to read the file path when `include()` is used by an autoloader. - * - * This will not be `null` when the autoloader tried to read a file. - */ - if (FileReadTrapStreamWrapper::$autoloadLocatedFile !== null) { - return [FileReadTrapStreamWrapper::$autoloadLocatedFile, $className, null]; - } - } - - return null; - }, - ); - } finally { - restore_error_handler(); - } - } - - private function silenceErrors(): void - { - set_error_handler(static fn (): bool => true); + return null; } } diff --git a/src/Reflection/BetterReflection/SourceLocator/FileReadTrapStreamWrapper.php b/src/Reflection/BetterReflection/SourceLocator/FileReadTrapStreamWrapper.php deleted file mode 100644 index e4c01a64b3..0000000000 --- a/src/Reflection/BetterReflection/SourceLocator/FileReadTrapStreamWrapper.php +++ /dev/null @@ -1,244 +0,0 @@ -readFromFile = false; - $this->seekPosition = 0; - - return true; - } - - /** - * Since we allow our wrapper's stream_open() to succeed, we need to - * simulate a successful read so autoloaders with require() don't explode. - * - * @param int $count - * - */ - public function stream_read($count): string - { - $this->readFromFile = true; - - // Dummy return value that is also valid PHP for require(). We'll read - // and process the file elsewhere, so it's OK to provide dummy data for - // this read. - return ''; - } - - /** - * Since we allowed the open to succeed, we should allow the close to occur - * as well. - * - */ - public function stream_close(): void - { - // no op - } - - /** - * Required for `require_once` and `include_once` to work per PHP.net - * comment referenced below. We delegate to url_stat(). - * - * @see https://www.php.net/manual/en/function.stream-wrapper-register.php#51855 - * - * @return mixed[]|bool - */ - public function stream_stat() - { - if (self::$autoloadLocatedFile === null) { - return false; - } - - return $this->url_stat(self::$autoloadLocatedFile, STREAM_URL_STAT_QUIET); - } - - /** - * url_stat is triggered by calls like "file_exists". The call to "file_exists" must not be overloaded. - * This function restores the original "file" stream, issues a call to "stat" to get the real results, - * and then re-registers the AutoloadSourceLocator stream wrapper. - * - * @internal do not call this method directly! This is stream wrapper - * voodoo logic that you **DO NOT** want to touch! - * - * @see https://php.net/manual/en/class.streamwrapper.php - * @see https://php.net/manual/en/streamwrapper.url-stat.php - * - * @param string $path - * @param int $flags - * - * @return mixed[]|bool - */ - public function url_stat($path, $flags) - { - if (self::$registeredStreamWrapperProtocols === null) { - throw new ShouldNotHappenException(self::class . ' not registered: cannot operate. Do not call this method directly.'); - } - - foreach (self::$registeredStreamWrapperProtocols as $protocol) { - stream_wrapper_restore($protocol); - } - - if (($flags & STREAM_URL_STAT_QUIET) !== 0) { - $result = @stat($path); - } else { - $result = stat($path); - } - - foreach (self::$registeredStreamWrapperProtocols as $protocol) { - stream_wrapper_unregister($protocol); - stream_wrapper_register($protocol, self::class); - } - - return $result; - } - - /** - * Simulates behavior of reading from an empty file. - * - */ - public function stream_eof(): bool - { - return $this->readFromFile; - } - - public function stream_flush(): bool - { - return true; - } - - public function stream_tell(): int - { - return $this->seekPosition; - } - - /** - * @param int $offset - * @param int $whence - */ - public function stream_seek($offset, $whence): bool - { - switch ($whence) { - // Behavior is the same for a zero-length file - case SEEK_SET: - case SEEK_END: - if ($offset < 0) { - return false; - } - $this->seekPosition = $offset; - return true; - - case SEEK_CUR: - if ($offset < 0) { - return false; - } - $this->seekPosition += $offset; - return true; - - default: - return false; - } - } - - /** - * @param int $option - * @param int $arg1 - * @param int $arg2 - */ - public function stream_set_option($option, $arg1, $arg2): bool - { - return false; - } - -}