From d1aa50969c8db12baff3e355d55f6f29a5a20119 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 17 Jan 2022 16:01:15 +0100 Subject: [PATCH] [ErrorHandler] ignore `@return` when there is an `@template` --- .github/expected-missing-return-types.diff | 101 ++++++++---------- .../ErrorHandler/DebugClassLoader.php | 7 ++ 2 files changed, 50 insertions(+), 58 deletions(-) diff --git a/.github/expected-missing-return-types.diff b/.github/expected-missing-return-types.diff index a7303fc130311..a77e0a0472a43 100644 --- a/.github/expected-missing-return-types.diff +++ b/.github/expected-missing-return-types.diff @@ -4,9 +4,10 @@ composer u -o SYMFONY_PATCH_TYPE_DECLARATIONS='force=2&php=8.0' php .github/patch-types.php head=$(sed '/^diff /Q' .github/expected-missing-return-types.diff) (echo "$head" && echo && git diff -U2 composer.json src/) > .github/expected-missing-return-types.diff +git checkout composer.json src/ diff --git a/composer.json b/composer.json -index 978743d34d..1f185f682c 100644 +index c7b7eac4c7..2b60fb6a19 100644 --- a/composer.json +++ b/composer.json @@ -180,5 +180,5 @@ @@ -155,7 +156,7 @@ index 6b1c6c5fbe..bb80ed461e 100644 + public function isFresh(ResourceInterface $resource, int $timestamp): bool; } diff --git a/src/Symfony/Component/Console/Application.php b/src/Symfony/Component/Console/Application.php -index 09234f5eb5..24d995ad6d 100644 +index 0ed5649b8a..6c814bf82c 100644 --- a/src/Symfony/Component/Console/Application.php +++ b/src/Symfony/Component/Console/Application.php @@ -218,5 +218,5 @@ class Application implements ResetInterface @@ -208,7 +209,7 @@ index 09234f5eb5..24d995ad6d 100644 { foreach ($command->getHelperSet() as $helper) { diff --git a/src/Symfony/Component/Console/Command/Command.php b/src/Symfony/Component/Console/Command/Command.php -index e69bae0982..3390628d0d 100644 +index 0bd3426c07..b38caf989e 100644 --- a/src/Symfony/Component/Console/Command/Command.php +++ b/src/Symfony/Component/Console/Command/Command.php @@ -171,5 +171,5 @@ class Command @@ -236,24 +237,24 @@ index 1d2b7bfb84..cb1f66152d 100644 + public function getName(): string; } diff --git a/src/Symfony/Component/Console/Input/InputInterface.php b/src/Symfony/Component/Console/Input/InputInterface.php -index 024da1884e..943790e875 100644 +index 3af991a76f..742e2508f3 100644 --- a/src/Symfony/Component/Console/Input/InputInterface.php +++ b/src/Symfony/Component/Console/Input/InputInterface.php -@@ -54,5 +54,5 @@ interface InputInterface +@@ -57,5 +57,5 @@ interface InputInterface * @return mixed */ - public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false); + public function getParameterOption(string|array $values, string|bool|int|float|array|null $default = false, bool $onlyParams = false): mixed; /** -@@ -84,5 +84,5 @@ interface InputInterface +@@ -87,5 +87,5 @@ interface InputInterface * @throws InvalidArgumentException When argument given doesn't exist */ - public function getArgument(string $name); + public function getArgument(string $name): mixed; /** -@@ -112,5 +112,5 @@ interface InputInterface +@@ -115,5 +115,5 @@ interface InputInterface * @throws InvalidArgumentException When option given doesn't exist */ - public function getOption(string $name); @@ -261,7 +262,7 @@ index 024da1884e..943790e875 100644 /** diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php -index e9fa5a6808..016e9d893a 100644 +index c2824f4578..032f5c2318 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -71,5 +71,5 @@ abstract class AbstractRecursivePass implements CompilerPassInterface @@ -383,7 +384,7 @@ index 479aeef880..272954c082 100644 + public function getFunctions(): array; } diff --git a/src/Symfony/Component/Form/AbstractExtension.php b/src/Symfony/Component/Form/AbstractExtension.php -index 5a077a42a6..62a234b116 100644 +index 79d61e8bc0..7f34d95d84 100644 --- a/src/Symfony/Component/Form/AbstractExtension.php +++ b/src/Symfony/Component/Form/AbstractExtension.php @@ -114,5 +114,5 @@ abstract class AbstractExtension implements FormExtensionInterface @@ -525,10 +526,10 @@ index 2f442cb536..d98909cfae 100644 + public function warmUp(string $cacheDir): array; } diff --git a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php -index 1289cf0ea9..dabeec97ee 100644 +index 3a3be3af49..971560c07b 100644 --- a/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php +++ b/src/Symfony/Component/HttpKernel/DataCollector/DataCollector.php -@@ -58,5 +58,5 @@ abstract class DataCollector implements DataCollectorInterface +@@ -59,5 +59,5 @@ abstract class DataCollector implements DataCollectorInterface * @return callable[] The casters to add to the cloner */ - protected function getCasters() @@ -546,7 +547,7 @@ index 1cb865fd66..f6f4efe7a7 100644 + public function getName(): string; } diff --git a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php -index eeec55593f..c12df944fc 100644 +index cf0e243c6b..292b907ea8 100644 --- a/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php +++ b/src/Symfony/Component/HttpKernel/HttpCache/HttpCache.php @@ -448,5 +448,5 @@ class HttpCache implements HttpKernelInterface, TerminableInterface @@ -557,7 +558,7 @@ index eeec55593f..c12df944fc 100644 { $this->surrogate?->addSurrogateCapability($request); diff --git a/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php b/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php -index fc70d8970d..9dde6d1f93 100644 +index 1557da575a..7e5a2a9859 100644 --- a/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php +++ b/src/Symfony/Component/HttpKernel/HttpKernelBrowser.php @@ -61,5 +61,5 @@ class HttpKernelBrowser extends AbstractBrowser @@ -610,23 +611,6 @@ index 125b6eae50..ac327e8981 100644 + public function createLockFromKey(Key $key, ?float $ttl = 300.0, bool $autoRelease = true): SharedLockInterface { $lock = new Lock($key, $this->store, $ttl, $autoRelease); -diff --git a/src/Symfony/Component/Messenger/Envelope.php b/src/Symfony/Component/Messenger/Envelope.php -index bb1194ad1b..27731b9cb0 100644 ---- a/src/Symfony/Component/Messenger/Envelope.php -+++ b/src/Symfony/Component/Messenger/Envelope.php -@@ -13,4 +13,5 @@ namespace Symfony\Component\Messenger; - - use Symfony\Component\Messenger\Stamp\StampInterface; -+use Symfony\Component\Messenger\Stamp\StampInterface as TStamp; - - /** -@@ -101,5 +102,5 @@ final class Envelope - * @return TStamp|null - */ -- public function last(string $stampFqcn): ?StampInterface -+ public function last(string $stampFqcn): ?TStamp - { - return isset($this->stamps[$stampFqcn]) ? end($this->stamps[$stampFqcn]) : null; diff --git a/src/Symfony/Component/OptionsResolver/OptionsResolver.php b/src/Symfony/Component/OptionsResolver/OptionsResolver.php index 205c15b4cd..e93e460ed1 100644 --- a/src/Symfony/Component/OptionsResolver/OptionsResolver.php @@ -771,7 +755,7 @@ index 2dd0e5efbf..95e01d8955 100644 { $name = str_replace('\\', '_', $class->name).'_'.$method->name; diff --git a/src/Symfony/Component/Routing/Router.php b/src/Symfony/Component/Routing/Router.php -index be653e4f00..e46300d474 100644 +index 83c10427a1..e113d4a194 100644 --- a/src/Symfony/Component/Routing/Router.php +++ b/src/Symfony/Component/Routing/Router.php @@ -178,5 +178,5 @@ class Router implements RouterInterface, RequestMatcherInterface @@ -813,7 +797,7 @@ index 7e401c3ff3..6b446ff376 100644 + public function vote(TokenInterface $token, mixed $subject, array $attributes): int; } diff --git a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php -index 9e2b02b603..c6a753f1f7 100644 +index 298bc78cd9..3ef4176dd8 100644 --- a/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php +++ b/src/Symfony/Component/Security/Core/Exception/AuthenticationException.php @@ -89,5 +89,5 @@ class AuthenticationException extends RuntimeException @@ -852,7 +836,7 @@ index 91271d14a3..100c2fb549 100644 + public function start(Request $request, AuthenticationException $authException = null): Response; } diff --git a/src/Symfony/Component/Security/Http/Firewall.php b/src/Symfony/Component/Security/Http/Firewall.php -index 546b77d22f..24038d4b94 100644 +index 0c313f8f09..acfc9f4b88 100644 --- a/src/Symfony/Component/Security/Http/Firewall.php +++ b/src/Symfony/Component/Security/Http/Firewall.php @@ -106,5 +106,5 @@ class Firewall implements EventSubscriberInterface @@ -873,7 +857,7 @@ index 480ea8ad6b..fa43d6a6e9 100644 + public function getListeners(Request $request): array; } diff --git a/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php b/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php -index 84a84ad1f3..6f66b6d32a 100644 +index f38069e471..0966eb3e89 100644 --- a/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php +++ b/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php @@ -35,5 +35,5 @@ interface DecoderInterface @@ -883,11 +867,11 @@ index 84a84ad1f3..6f66b6d32a 100644 + public function decode(string $data, string $format, array $context = []): mixed; /** -@@ -44,4 +44,4 @@ interface DecoderInterface +@@ -45,4 +45,4 @@ interface DecoderInterface * @return bool */ -- public function supportsDecoding(string $format); -+ public function supportsDecoding(string $format): bool; +- public function supportsDecoding(string $format /*, array $context = [] */); ++ public function supportsDecoding(string $format /*, array $context = [] */): bool; } diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 7f86ed8d78..cf084423ec 100644 @@ -915,51 +899,52 @@ index 7f86ed8d78..cf084423ec 100644 { if (null !== $object = $this->extractObjectToPopulate($class, $context, self::OBJECT_TO_POPULATE)) { diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php -index 3e1e7edc8e..e025b2bc4a 100644 +index a8943113c4..2983dabd0f 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php -@@ -136,5 +136,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer - * {@inheritdoc} +@@ -138,5 +138,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer + * @param array $context */ -- public function supportsNormalization(mixed $data, string $format = null) -+ public function supportsNormalization(mixed $data, string $format = null): bool +- public function supportsNormalization(mixed $data, string $format = null /*, array $context = [] */) ++ public function supportsNormalization(mixed $data, string $format = null /*, array $context = [] */): bool { return \is_object($data) && !$data instanceof \Traversable; -@@ -144,5 +144,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer +@@ -146,5 +146,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer * {@inheritdoc} */ - public function normalize(mixed $object, string $format = null, array $context = []) + public function normalize(mixed $object, string $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null { if (!isset($context['cache_key'])) { -@@ -277,5 +277,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer +@@ -279,5 +279,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer * {@inheritdoc} */ - protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, array|bool $allowedAttributes, string $format = null) + protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, array|bool $allowedAttributes, string $format = null): object { if ($this->classDiscriminatorResolver && $mapping = $this->classDiscriminatorResolver->getMappingForClass($class)) { -@@ -339,5 +339,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer +@@ -341,5 +341,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer * @return string[] */ - abstract protected function extractAttributes(object $object, string $format = null, array $context = []); + abstract protected function extractAttributes(object $object, string $format = null, array $context = []): array; /** -@@ -346,10 +346,10 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer +@@ -348,5 +348,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer * @return mixed */ - abstract protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []); + abstract protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []): mixed; /** - * {@inheritdoc} +@@ -355,5 +355,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer + * @param array $context */ -- public function supportsDenormalization(mixed $data, string $type, string $format = null) -+ public function supportsDenormalization(mixed $data, string $type, string $format = null): bool +- public function supportsDenormalization(mixed $data, string $type, string $format = null /*, array $context = [] */) ++ public function supportsDenormalization(mixed $data, string $type, string $format = null /*, array $context = [] */): bool { return class_exists($type) || (interface_exists($type, false) && $this->classDiscriminatorResolver && null !== $this->classDiscriminatorResolver->getMappingForClass($type)); -@@ -359,5 +359,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer +@@ -363,5 +363,5 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer * {@inheritdoc} */ - public function denormalize(mixed $data, string $type, string $format = null, array $context = []) @@ -967,7 +952,7 @@ index 3e1e7edc8e..e025b2bc4a 100644 { if (!isset($context['cache_key'])) { diff --git a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php -index 5e94400b80..726d89cbb1 100644 +index 1c708738a1..3b6c9d5056 100644 --- a/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php @@ -45,5 +45,5 @@ interface DenormalizerInterface @@ -977,14 +962,14 @@ index 5e94400b80..726d89cbb1 100644 + public function denormalize(mixed $data, string $type, string $format = null, array $context = []): mixed; /** -@@ -56,4 +56,4 @@ interface DenormalizerInterface +@@ -57,4 +57,4 @@ interface DenormalizerInterface * @return bool */ -- public function supportsDenormalization(mixed $data, string $type, string $format = null); -+ public function supportsDenormalization(mixed $data, string $type, string $format = null): bool; +- public function supportsDenormalization(mixed $data, string $type, string $format = null /*, array $context = [] */); ++ public function supportsDenormalization(mixed $data, string $type, string $format = null /*, array $context = [] */): bool; } diff --git a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php -index 30eeafb47b..a7a60ad2f2 100644 +index 741f19e50b..acf3be931b 100644 --- a/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php +++ b/src/Symfony/Component/Serializer/Normalizer/NormalizerInterface.php @@ -37,5 +37,5 @@ interface NormalizerInterface @@ -994,11 +979,11 @@ index 30eeafb47b..a7a60ad2f2 100644 + public function normalize(mixed $object, string $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null; /** -@@ -47,4 +47,4 @@ interface NormalizerInterface +@@ -48,4 +48,4 @@ interface NormalizerInterface * @return bool */ -- public function supportsNormalization(mixed $data, string $format = null); -+ public function supportsNormalization(mixed $data, string $format = null): bool; +- public function supportsNormalization(mixed $data, string $format = null /*, array $context = [] */); ++ public function supportsNormalization(mixed $data, string $format = null /*, array $context = [] */): bool; } diff --git a/src/Symfony/Component/Templating/Helper/HelperInterface.php b/src/Symfony/Component/Templating/Helper/HelperInterface.php index 5dade65db5..db0d0a00ea 100644 diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php index 85b486a97dede..3255636aa5fb0 100644 --- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php +++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php @@ -371,9 +371,12 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array $parent = get_parent_class($class) ?: null; self::$returnTypes[$class] = []; + $classIsTemplate = false; // Detect annotations on the class if ($doc = $this->parsePhpDoc($refl)) { + $classIsTemplate = isset($doc['template']); + foreach (['final', 'deprecated', 'internal'] as $annotation) { if (null !== $description = $doc[$annotation][0] ?? null) { self::${$annotation}[$class] = '' !== $description ? ' '.$description.(preg_match('/[.!]$/', $description) ? '' : '.') : '.'; @@ -517,6 +520,10 @@ public function checkAnnotations(\ReflectionClass $refl, string $class): array // To read method annotations $doc = $this->parsePhpDoc($method); + if (($classIsTemplate || isset($doc['template'])) && $method->hasReturnType()) { + unset($doc['return']); + } + if (isset(self::$annotatedParameters[$class][$method->name])) { $definedParameters = []; foreach ($method->getParameters() as $parameter) {