diff --git a/.github/patch-types.php b/.github/patch-types.php index 3657545ed6b9..ca33ef47a61e 100644 --- a/.github/patch-types.php +++ b/.github/patch-types.php @@ -1,7 +1,8 @@ * @author Christophe Coevoet * @author Nicolas Grekas @@ -141,6 +154,7 @@ class DebugClassLoader private $isFinder; private $loaded = []; private $patchTypes; + private static $caseCheck; private static $checkedClasses = []; private static $final = []; @@ -160,6 +174,10 @@ public function __construct(callable $classLoader) $this->classLoader = $classLoader; $this->isFinder = \is_array($classLoader) && method_exists($classLoader[0], 'findFile'); parse_str(getenv('SYMFONY_PATCH_TYPE_DECLARATIONS') ?: '', $this->patchTypes); + $this->patchTypes += [ + 'force' => null, + 'php' => null, + ]; if (!isset(self::$caseCheck)) { $file = file_exists(__FILE__) ? __FILE__ : rtrim(realpath('.'), \DIRECTORY_SEPARATOR); @@ -551,15 +569,14 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } } - $forcePatchTypes = $this->patchTypes['force'] ?? null; + $forcePatchTypes = $this->patchTypes['force']; - if ($canAddReturnType = null !== $forcePatchTypes && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { + if ($canAddReturnType = $forcePatchTypes && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { if ('void' !== (self::MAGIC_METHODS[$method->name] ?? 'void')) { $this->patchTypes['force'] = $forcePatchTypes ?: 'docblock'; } - $canAddReturnType = ($this->patchTypes['force'] ?? false) - || false !== strpos($refl->getFileName(), \DIRECTORY_SEPARATOR.'Tests'.\DIRECTORY_SEPARATOR) + $canAddReturnType = false !== strpos($refl->getFileName(), \DIRECTORY_SEPARATOR.'Tests'.\DIRECTORY_SEPARATOR) || $refl->isFinal() || $method->isFinal() || $method->isPrivate() @@ -570,20 +587,20 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array } if (null !== ($returnType = self::$returnTypes[$class][$method->name] ?? self::MAGIC_METHODS[$method->name] ?? null) && !$method->hasReturnType() && !($doc && preg_match('/\n\s+\* @return +(\S+)/', $doc))) { - if ('void' === $returnType) { + list($normalizedType, $returnType, $declaringClass, $declaringFile) = \is_string($returnType) ? [$returnType, $returnType, '', ''] : $returnType; + + if ('void' === $normalizedType) { $canAddReturnType = false; } - list($normalizedType, $returnType, $declaringClass, $declaringFile) = \is_string($returnType) ? [$returnType, $returnType, '', ''] : $returnType; - - if ($canAddReturnType && 'docblock' !== ($this->patchTypes['force'] ?? false)) { + if ($canAddReturnType && 'docblock' !== $this->patchTypes['force']) { $this->patchMethod($method, $returnType, $declaringFile, $normalizedType); } if (strncmp($ns, $declaringClass, $len)) { - if ($canAddReturnType && 'docblock' === ($this->patchTypes['force'] ?? false) && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { + if ($canAddReturnType && 'docblock' === $this->patchTypes['force'] && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) { $this->patchMethod($method, $returnType, $declaringFile, $normalizedType); - } elseif ('' !== $declaringClass) { + } elseif ('' !== $declaringClass && null !== $this->patchTypes['force']) { $deprecations[] = sprintf('Method "%s::%s()" will return "%s" as of its next major version. Doing the same in child class "%s" will be required when upgrading.', $declaringClass, $method->name, $normalizedType, $className); } } @@ -820,7 +837,7 @@ private function setReturnType(string $types, \ReflectionMethod $method, ?string } elseif ($n !== $normalizedType || !preg_match('/^\\\\?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $n)) { if ($iterable) { $normalizedType = $returnType = 'iterable'; - } elseif ($object) { + } elseif ($object && 'object' === $this->patchTypes['force']) { $normalizedType = $returnType = 'object'; } else { // ignore multi-types return declarations @@ -947,7 +964,7 @@ private function patchMethod(\ReflectionMethod $method, string $returnType, stri } } - if ('docblock' === ($this->patchTypes['force'] ?? null) || ('object' === $normalizedType && ($this->patchTypes['php71-compat'] ?? false))) { + if ('docblock' === $this->patchTypes['force'] || ('object' === $normalizedType && '7.1' === $this->patchTypes['php'])) { $returnType = implode('|', $returnType); if ($method->getDocComment()) { @@ -1015,7 +1032,7 @@ private static function getUseStatements(string $file): array private function fixReturnStatements(\ReflectionMethod $method, string $returnType) { - if (($this->patchTypes['php71-compat'] ?? false) && 'object' === ltrim($returnType, '?') && 'docblock' !== ($this->patchTypes['force'] ?? null)) { + if ('7.1' === $this->patchTypes['php'] && 'object' === ltrim($returnType, '?') && 'docblock' !== $this->patchTypes['force']) { return; } @@ -1026,7 +1043,7 @@ private function fixReturnStatements(\ReflectionMethod $method, string $returnTy $fixedCode = $code = file($file); $i = (self::$fileOffsets[$file] ?? 0) + $method->getStartLine(); - if ('?' !== $returnType && 'docblock' !== ($this->patchTypes['force'] ?? null)) { + if ('?' !== $returnType && 'docblock' !== $this->patchTypes['force']) { $fixedCode[$i - 1] = preg_replace('/\)(;?\n)/', "): $returnType\\1", $code[$i - 1]); } diff --git a/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php index fd8d934eebdf..99bb28cd5671 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php +++ b/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php @@ -16,16 +16,15 @@ class DebugClassLoaderTest extends TestCase { - /** - * @var int Error reporting level before running tests - */ + private $patchTypes; private $errorReporting; - private $loader; protected function setUp(): void { + $this->patchTypes = getenv('SYMFONY_PATCH_TYPE_DECLARATIONS'); $this->errorReporting = error_reporting(E_ALL); + putenv('SYMFONY_PATCH_TYPE_DECLARATIONS=force=0'); $this->loader = [new DebugClassLoader([new ClassLoader(), 'loadClass']), 'loadClass']; spl_autoload_register($this->loader, true, true); } @@ -34,6 +33,7 @@ protected function tearDown(): void { spl_autoload_unregister($this->loader); error_reporting($this->errorReporting); + putenv('SYMFONY_PATCH_TYPE_DECLARATIONS'.(false !== $this->patchTypes ? '='.$this->patchTypes : '')); } /**