From 847a96386feebc5033418115789a35c5f665b21a Mon Sep 17 00:00:00 2001
From: Larry Garfield <larry@garfieldtech.com>
Date: Tue, 26 Jul 2022 17:12:42 -0500
Subject: [PATCH] [!!!][TASK] Resolve most #[ReturnTypeWillChange] attributes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Sets return types for most classes that implement
PHP SPL classes. Only "mixed" return types are not
set: That would be hard breaking for extensions
that support both core v11 and v12, since it is not
PHP 7.4 compatible. Those places are marked with
an @todo to switch to mixed in v13.

Resolves: #98035
Releases: main
Change-Id: Icd62a69270a6718c8356108e55a0729779609c53
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75310
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
---
 Build/phpstan/phpstan-baseline.neon           |  5 ---
 .../ModuleApi/ModuleDataStorageCollection.php |  5 +--
 .../Classes/Controller/MfaAjaxController.php  | 14 +++---
 .../Classes/Tree/SortedTreeNodeCollection.php | 12 +++---
 .../Classes/Tree/TreeNodeCollection.php       | 14 ++----
 .../Collection/AbstractRecordCollection.php   | 34 +++------------
 typo3/sysext/core/Classes/Log/LogRecord.php   | 13 +++---
 .../Classes/Messaging/FlashMessageQueue.php   |  8 +---
 .../Collection/AbstractFileCollection.php     |  1 +
 .../core/Classes/Resource/MetaDataAspect.php  |  4 +-
 .../Search/Result/EmptyFileSearchResult.php   | 20 +--------
 .../core/Classes/Routing/SiteRouteResult.php  | 15 ++-----
 ...dedToMethodSignaturesOrClassProperties.rst | 15 +++++++
 .../Unit/Messaging/FlashMessageQueueTest.php  | 38 ----------------
 .../Classes/Mvc/Controller/Arguments.php      | 38 ++++------------
 .../Persistence/Generic/LazyLoadingProxy.php  | 18 +++-----
 .../Persistence/Generic/LazyObjectStorage.php |  4 +-
 .../Persistence/Generic/QueryResult.php       | 43 +++++--------------
 .../Classes/Persistence/ObjectStorage.php     | 30 +++++--------
 .../Controller/MaintenanceController.php      |  6 ++-
 .../Classes/Middleware/Maintenance.php        |  6 ++-
 21 files changed, 101 insertions(+), 242 deletions(-)
 delete mode 100644 typo3/sysext/core/Tests/Unit/Messaging/FlashMessageQueueTest.php

diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon
index 39134584be71..d7a375fc1737 100644
--- a/Build/phpstan/phpstan-baseline.neon
+++ b/Build/phpstan/phpstan-baseline.neon
@@ -135,11 +135,6 @@ parameters:
 			count: 1
 			path: ../../typo3/sysext/backend/Classes/Tree/Renderer/UnorderedListTreeRenderer.php
 
-		-
-			message: "#^Method TYPO3\\\\CMS\\\\Backend\\\\Tree\\\\TreeNodeCollection\\:\\:asort\\(\\) should return bool but return statement is missing\\.$#"
-			count: 1
-			path: ../../typo3/sysext/backend/Classes/Tree/TreeNodeCollection.php
-
 		-
 			message: "#^Variable \\$columnsConfiguration in empty\\(\\) always exists and is not falsy\\.$#"
 			count: 1
diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php
index 745b355d5668..759b68b52fd8 100644
--- a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php
+++ b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php
@@ -29,11 +29,8 @@ class ModuleDataStorageCollection extends \SplObjectStorage
 
     /**
      * @param object $object
-     * @return string
-     * @todo Set return type to string as breaking patch in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function getHash($object)
+    public function getHash($object): string
     {
         if ($object instanceof ModuleInterface) {
             return $object->getIdentifier();
diff --git a/typo3/sysext/backend/Classes/Controller/MfaAjaxController.php b/typo3/sysext/backend/Classes/Controller/MfaAjaxController.php
index 8c3af9c1c82a..d3826c353e59 100644
--- a/typo3/sysext/backend/Classes/Controller/MfaAjaxController.php
+++ b/typo3/sysext/backend/Classes/Controller/MfaAjaxController.php
@@ -157,14 +157,16 @@ class MfaAjaxController
      */
     protected function getResponseData(bool $success, string $message, ?AbstractUserAuthentication $user = null): array
     {
+        $flashMessageQueue = new FlashMessageQueue('backend');
+        $flashMessageQueue->enqueue(
+            new FlashMessage(
+                $message,
+                $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.' . ($success ? 'success' : 'error'))
+            )
+        );
         $payload = [
             'success' => $success,
-            'status' => (new FlashMessageQueue('backend'))->enqueue(
-                new FlashMessage(
-                    $message,
-                    $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mfa.xlf:ajax.' . ($success ? 'success' : 'error'))
-                )
-            ),
+            'status' => $flashMessageQueue,
         ];
 
         if ($user !== null) {
diff --git a/typo3/sysext/backend/Classes/Tree/SortedTreeNodeCollection.php b/typo3/sysext/backend/Classes/Tree/SortedTreeNodeCollection.php
index f79770ba589c..8c707654e18d 100644
--- a/typo3/sysext/backend/Classes/Tree/SortedTreeNodeCollection.php
+++ b/typo3/sysext/backend/Classes/Tree/SortedTreeNodeCollection.php
@@ -26,7 +26,7 @@ class SortedTreeNodeCollection extends TreeNodeCollection
     /**
      * Checks if a specific node is inside the collection
      *
-     * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
+     * @param TreeNode $node
      * @return bool
      */
     public function contains(TreeNode $node)
@@ -37,7 +37,7 @@ class SortedTreeNodeCollection extends TreeNodeCollection
     /**
      * Returns the offset key of given node
      *
-     * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
+     * @param TreeNode $node
      * @return int
      */
     protected function offsetOf(TreeNode $node)
@@ -48,7 +48,7 @@ class SortedTreeNodeCollection extends TreeNodeCollection
     /**
      * Binary search that returns the offset of a given node
      *
-     * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
+     * @param TreeNode $node
      * @param int $start
      * @param int $end
      * @return int
@@ -89,11 +89,9 @@ class SortedTreeNodeCollection extends TreeNodeCollection
     /**
      * Adds a node to the internal list in a sorted approach
      *
-     * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
-     * @todo: Set return type to void in v12 as breaking patch and drop #[\ReturnTypeWillChange]
+     * @param TreeNode $node
      */
-    #[\ReturnTypeWillChange]
-    public function append($node)
+    public function append($node): void
     {
         parent::append($node);
         $this->asort();
diff --git a/typo3/sysext/backend/Classes/Tree/TreeNodeCollection.php b/typo3/sysext/backend/Classes/Tree/TreeNodeCollection.php
index 8bda5c160350..73d340252875 100644
--- a/typo3/sysext/backend/Classes/Tree/TreeNodeCollection.php
+++ b/typo3/sysext/backend/Classes/Tree/TreeNodeCollection.php
@@ -43,12 +43,11 @@ class TreeNodeCollection extends \ArrayObject
      * Sorts the internal nodes array
      *
      * @param int $flags Optional parameter, ignored. Added to be compatible with asort method signature in PHP 8.
-     * @todo: Set return type to void in v12 as breaking patch and drop #[\ReturnTypeWillChange]
      */
-    #[\ReturnTypeWillChange]
-    public function asort($flags = SORT_REGULAR)
+    public function asort($flags = SORT_REGULAR): bool
     {
         $this->uasort([$this, 'nodeCompare']);
+        return true;
     }
 
     /**
@@ -67,11 +66,8 @@ class TreeNodeCollection extends \ArrayObject
 
     /**
      * Returns class state to be serialized.
-     *
-     * @todo: Change signature to __serialize(): array in v12
      */
-    #[\ReturnTypeWillChange]
-    public function __serialize()
+    public function __serialize(): array
     {
         return $this->toArray();
     }
@@ -80,10 +76,8 @@ class TreeNodeCollection extends \ArrayObject
      * Fills the current node with the given serialized information
      *
      * @throws Exception if the deserialized object type is not identical to the current one
-     * @todo: Change signature to __unserialize(array $arrayRepresentation): void in v12
      */
-    #[\ReturnTypeWillChange]
-    public function __unserialize($arrayRepresentation)
+    public function __unserialize($arrayRepresentation): void
     {
         if ($arrayRepresentation['serializeClassName'] !== static::class) {
             throw new Exception('Deserialized object type is not identical!', 1294586647);
diff --git a/typo3/sysext/core/Classes/Collection/AbstractRecordCollection.php b/typo3/sysext/core/Classes/Collection/AbstractRecordCollection.php
index 18f2b3931ef1..b12f8c48d44c 100644
--- a/typo3/sysext/core/Classes/Collection/AbstractRecordCollection.php
+++ b/typo3/sysext/core/Classes/Collection/AbstractRecordCollection.php
@@ -95,12 +95,10 @@ abstract class AbstractRecordCollection implements RecordCollectionInterface, Pe
     }
 
     /**
-     * (PHP 5 >= 5.1.0)
      * Return the current element
      *
-     * @link https://php.net/manual/en/iterator.current.php
      * @return mixed Can return any type.
-     * @todo: Set return type to mixed when PHP >= 8.0 is required and drop #[\ReturnTypeWillChange]
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function current()
@@ -109,25 +107,18 @@ abstract class AbstractRecordCollection implements RecordCollectionInterface, Pe
     }
 
     /**
-     * (PHP 5 >= 5.1.0)
      * Move forward to next element
-     *
-     * @link https://php.net/manual/en/iterator.next.php
-     * @todo: Set return type to void in v12 as breaking patch and drop #[\ReturnTypeWillChange]
      */
-    #[\ReturnTypeWillChange]
-    public function next()
+    public function next(): void
     {
         $this->storage->next();
     }
 
     /**
-     * (PHP 5 >= 5.1.0)
      * Return the key of the current element
      *
-     * @link https://php.net/manual/en/iterator.key.php
      * @return int|string 0 on failure.
-     * @todo: Set return type to mixed when PHP >= 8.0 is required and drop #[\ReturnTypeWillChange]
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function key()
@@ -137,28 +128,21 @@ abstract class AbstractRecordCollection implements RecordCollectionInterface, Pe
     }
 
     /**
-     * (PHP 5 >= 5.1.0)
      * Checks if current position is valid
      *
-     * @link https://php.net/manual/en/iterator.valid.php
-     * @return bool The return value will be casted to boolean and then evaluated.
-     * @todo: Set return type to bool in v12 as breaking patch and drop #[\ReturnTypeWillChange]
+     * @return bool The return value will be cast to boolean and then evaluated.
      */
-    #[\ReturnTypeWillChange]
-    public function valid()
+    public function valid(): bool
     {
         return $this->storage->valid();
     }
 
     /**
-     * (PHP 5 >= 5.1.0)
      * Rewind the Iterator to the first element
      *
-     * @link https://php.net/manual/en/iterator.rewind.php
      * @todo: Set return type to void in v12 as breaking patch and drop #[\ReturnTypeWillChange]
      */
-    #[\ReturnTypeWillChange]
-    public function rewind()
+    public function rewind(): void
     {
         $this->storage->rewind();
     }
@@ -182,15 +166,11 @@ abstract class AbstractRecordCollection implements RecordCollectionInterface, Pe
     }
 
     /**
-     * (PHP 5 >= 5.1.0)
      * Count elements of an object
      *
-     * @link https://php.net/manual/en/countable.count.php
      * @return int The custom count as an integer.
-     * @todo: Set return type to in in v12 as breaking patch and drop #[\ReturnTypeWillChange]
      */
-    #[\ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return $this->storage->count();
     }
diff --git a/typo3/sysext/core/Classes/Log/LogRecord.php b/typo3/sysext/core/Classes/Log/LogRecord.php
index 6d245c55f0d5..a4e867fc173e 100644
--- a/typo3/sysext/core/Classes/Log/LogRecord.php
+++ b/typo3/sysext/core/Classes/Log/LogRecord.php
@@ -17,6 +17,8 @@ namespace TYPO3\CMS\Core\Log;
 
 /**
  * Log record
+ *
+ * @todo: Consider declaring this DTO final
  */
 class LogRecord implements \ArrayAccess
 {
@@ -290,10 +292,8 @@ class LogRecord implements \ArrayAccess
      * Checks whether an offset exists, required by ArrayAccess interface
      *
      * @param mixed $offset
-     * @return bool
      */
-    #[\ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         $offsetExists = false;
         if (in_array($offset, $this->gettableProperties, true) && isset($this->{$offset})) {
@@ -307,6 +307,7 @@ class LogRecord implements \ArrayAccess
      *
      * @param mixed $offset
      * @return mixed
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function offsetGet($offset)
@@ -323,8 +324,7 @@ class LogRecord implements \ArrayAccess
      * @param mixed $offset
      * @param mixed $value
      */
-    #[\ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         if (in_array($offset, $this->settableProperties, true)) {
             $this->{$offset} = $offset;
@@ -336,8 +336,7 @@ class LogRecord implements \ArrayAccess
      *
      * @param mixed $offset
      */
-    #[\ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         if (in_array($offset, $this->settableProperties, true)) {
             unset($this->{$offset});
diff --git a/typo3/sysext/core/Classes/Messaging/FlashMessageQueue.php b/typo3/sysext/core/Classes/Messaging/FlashMessageQueue.php
index 82f303a93877..f9766f513618 100644
--- a/typo3/sysext/core/Classes/Messaging/FlashMessageQueue.php
+++ b/typo3/sysext/core/Classes/Messaging/FlashMessageQueue.php
@@ -60,11 +60,8 @@ class FlashMessageQueue extends \SplQueue implements \JsonSerializable
      *
      * @param FlashMessage $message Instance of \TYPO3\CMS\Core\Messaging\FlashMessage, representing a message
      * @throws \TYPO3\CMS\Core\Exception
-     * @return FlashMessageQueue Self to allow chaining
-     * @todo: Set return type to void in v12 as breaking patch and drop #[\ReturnTypeWillChange]
      */
-    #[\ReturnTypeWillChange]
-    public function enqueue($message): FlashMessageQueue
+    public function enqueue($message): void
     {
         if (!($message instanceof FlashMessage)) {
             throw new Exception(
@@ -77,7 +74,6 @@ class FlashMessageQueue extends \SplQueue implements \JsonSerializable
         } else {
             parent::enqueue($message);
         }
-        return $this;
     }
 
     /**
@@ -91,7 +87,7 @@ class FlashMessageQueue extends \SplQueue implements \JsonSerializable
     /**
      * This method is empty, as it will not move any flash message (e.g. from the session)
      *
-     * @todo: Set return type to mixed when PHP >= 8.0 is required and drop #[\ReturnTypeWillChange]
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function dequeue()
diff --git a/typo3/sysext/core/Classes/Resource/Collection/AbstractFileCollection.php b/typo3/sysext/core/Classes/Resource/Collection/AbstractFileCollection.php
index 6f145982416d..ff517e026a0f 100644
--- a/typo3/sysext/core/Classes/Resource/Collection/AbstractFileCollection.php
+++ b/typo3/sysext/core/Classes/Resource/Collection/AbstractFileCollection.php
@@ -78,6 +78,7 @@ abstract class AbstractFileCollection extends AbstractRecordCollection
      * Return the key of the current element
      *
      * @return string
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function key()
diff --git a/typo3/sysext/core/Classes/Resource/MetaDataAspect.php b/typo3/sysext/core/Classes/Resource/MetaDataAspect.php
index e197b25e2658..e7d4eac7fd01 100644
--- a/typo3/sysext/core/Classes/Resource/MetaDataAspect.php
+++ b/typo3/sysext/core/Classes/Resource/MetaDataAspect.php
@@ -98,7 +98,7 @@ class MetaDataAspect implements \ArrayAccess, \Countable, \Iterator
     /**
      * @param mixed $offset
      * @return mixed
-     * @todo Set return type to mixed as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function offsetGet($offset)
@@ -144,7 +144,7 @@ class MetaDataAspect implements \ArrayAccess, \Countable, \Iterator
      * Gets the current value of iteration
      *
      * @return mixed
-     * @todo Set return type to mixed as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function current()
diff --git a/typo3/sysext/core/Classes/Resource/Search/Result/EmptyFileSearchResult.php b/typo3/sysext/core/Classes/Resource/Search/Result/EmptyFileSearchResult.php
index cef874fc1983..48e01b03508c 100644
--- a/typo3/sysext/core/Classes/Resource/Search/Result/EmptyFileSearchResult.php
+++ b/typo3/sysext/core/Classes/Resource/Search/Result/EmptyFileSearchResult.php
@@ -22,18 +22,13 @@ namespace TYPO3\CMS\Core\Resource\Search\Result;
  */
 class EmptyFileSearchResult implements FileSearchResultInterface
 {
-    /**
-     * @return int
-     * @see Countable::count()
-     */
     public function count(): int
     {
         return 0;
     }
 
     /**
-     * @see Iterator::current()
-     * @todo change return type to mixed in TYPO3 v12 (breaking).
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function current(): void
@@ -42,8 +37,7 @@ class EmptyFileSearchResult implements FileSearchResultInterface
     }
 
     /**
-     * @see Iterator::key()
-     * @todo change return type to mixed in TYPO3 v12 (breaking).
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function key(): void
@@ -51,26 +45,16 @@ class EmptyFileSearchResult implements FileSearchResultInterface
         // Noop
     }
 
-    /**
-     * @see Iterator::next()
-     */
     public function next(): void
     {
         // Noop
     }
 
-    /**
-     * @see Iterator::rewind()
-     */
     public function rewind(): void
     {
         // Noop
     }
 
-    /**
-     * @return bool
-     * @see Iterator::valid()
-     */
     public function valid(): bool
     {
         return false;
diff --git a/typo3/sysext/core/Classes/Routing/SiteRouteResult.php b/typo3/sysext/core/Classes/Routing/SiteRouteResult.php
index eba5b416367d..6a486f8d2e19 100644
--- a/typo3/sysext/core/Classes/Routing/SiteRouteResult.php
+++ b/typo3/sysext/core/Classes/Routing/SiteRouteResult.php
@@ -98,11 +98,10 @@ class SiteRouteResult implements RouteResultInterface
     /**
      * @param mixed $offset
      * @return mixed|UriInterface|string|SiteInterface|SiteLanguage
-     * @todo Set parameter type for $offset to mixed as breaking change in v12.
-     * @todo Set return type to mixed as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): mixed
     {
         switch ($offset) {
             case 'uri':
@@ -121,11 +120,8 @@ class SiteRouteResult implements RouteResultInterface
     /**
      * @param mixed $offset
      * @param mixed $value
-     * @todo Set parameter type for $offset and $value to mixed as breaking change in v12.
-     * @todo Set return type to mixed as breaking change in v12 and remove #[\ReturnTypeWillChange].
      */
-    #[\ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         switch ($offset) {
             case 'uri':
@@ -144,11 +140,8 @@ class SiteRouteResult implements RouteResultInterface
 
     /**
      * @param mixed $offset
-     * @todo Set parameter type for $offset to mixed as breaking change in v12.
-     * @todo Set return type to void as breaking change in v12 and remove #[\ReturnTypeWillChange].
      */
-    #[\ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         switch ($offset) {
             case 'uri':
diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97210-TypesAddedToMethodSignaturesOrClassProperties.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97210-TypesAddedToMethodSignaturesOrClassProperties.rst
index 6910c1bc0d0b..861cb28e6614 100644
--- a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97210-TypesAddedToMethodSignaturesOrClassProperties.rst
+++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97210-TypesAddedToMethodSignaturesOrClassProperties.rst
@@ -13,8 +13,18 @@ The following PHP classes have had parameter and return types added to some or
 all of their method signatures. The types are consistent with existing
 docblock-documented type expectations and existing behavior.
 
+- :php:`\TYPO3\CMS\Adminpanel\ModuleApi\ModuleDataStorageCollection`
+- :php:`\TYPO3\CMS\Backend\Tree\SortedTreeNodeCollection`
+- :php:`\TYPO3\CMS\Backend\Tree\TreeNodeCollection`
+- :php:`\TYPO3\CMS\Core\Collection\AbstractRecordCollection`
 - :php:`\TYPO3\CMS\Core\LinkHandling\FileLinkHandler`
+- :php:`\TYPO3\CMS\Core\Log\LogRecord`
+- :php:`\TYPO3\CMS\Core\Messaging\FlashMessageQueue`
 - :php:`\TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider`
+- :php:`\TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection`
+- :php:`\TYPO3\CMS\Core\Resource\MetaDataAspect`
+- :php:`\TYPO3\CMS\Core\Resource\Search\Result\EmptyFileSearchResult`
+- :php:`\TYPO3\CMS\Core\Routing\SiteRouteResult`
 - :php:`\TYPO3\CMS\Core\Utility\ArrayUtility`
 - :php:`\TYPO3\CMS\Core\Utility\ClassNamingUtility`
 - :php:`\TYPO3\CMS\Core\Utility\CsvUtility`
@@ -29,6 +39,11 @@ docblock-documented type expectations and existing behavior.
 - :php:`\TYPO3\CMS\Core\Utility\RootlineUtility`
 - :php:`\TYPO3\CMS\Core\Utility\StringUtility`
 - :php:`\TYPO3\CMS\Core\Utility\VersionNumberUtility`
+- :php:`\TYPO3\CMS\Extbase\Mvc\Controller\Arguments`
+- :php:`\TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage`
+- :php:`\TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy`
+- :php:`\TYPO3\CMS\Extbase\Persistence\ObjectStorage`
+- :php:`\TYPO3\CMS\Extbase\Persistence\QueryResult`
 
 The following PHP classes have added public class property types:
 
diff --git a/typo3/sysext/core/Tests/Unit/Messaging/FlashMessageQueueTest.php b/typo3/sysext/core/Tests/Unit/Messaging/FlashMessageQueueTest.php
deleted file mode 100644
index ca080a36489f..000000000000
--- a/typo3/sysext/core/Tests/Unit/Messaging/FlashMessageQueueTest.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-namespace TYPO3\CMS\Core\Tests\Unit\Messaging;
-
-use TYPO3\CMS\Core\Messaging\FlashMessage;
-use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
-use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
-
-/**
- * Test case
- */
-class FlashMessageQueueTest extends UnitTestCase
-{
-    /**
-     * @test
-     */
-    public function jsonSerializeReturnsArrayWithMessages(): void
-    {
-        $message = new FlashMessage('testMessage');
-        $subject= (new FlashMessageQueue('testing'))->enqueue($message);
-        self::assertEquals([ $message ], $subject->jsonSerialize());
-    }
-}
diff --git a/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php b/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php
index 1ba3cfd3c368..8ff547beebd8 100644
--- a/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php
+++ b/typo3/sysext/extbase/Classes/Mvc/Controller/Arguments.php
@@ -50,11 +50,8 @@ class Arguments extends \ArrayObject
      * @param mixed $offset Offset - not used here
      * @param mixed $value The argument
      * @throws \InvalidArgumentException if the argument is not a valid Controller Argument object
-     * @todo Set parameter type for $offset and $value to mixed or correct union type as breaking change in v12.
-     * @todo Set return type to mixed as breaking change in v12 and remove #[\ReturnTypeWillChange].
      */
-    #[\ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         if (!$value instanceof Argument) {
             throw new \InvalidArgumentException('Controller arguments must be valid TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument objects.', 1187953786);
@@ -69,11 +66,8 @@ class Arguments extends \ArrayObject
      *
      * @param mixed $value The value
      * @throws \InvalidArgumentException if the argument is not a valid Controller Argument object
-     * @todo Set parameter type for $value to mixed or correct union type as breaking change in v12.
-     * @todo Set return type to void as breaking change in v12 and remove #[\ReturnTypeWillChange].
      */
-    #[\ReturnTypeWillChange]
-    public function append($value)
+    public function append($value): void
     {
         if (!$value instanceof Argument) {
             throw new \InvalidArgumentException('Controller arguments must be valid TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Argument objects.', 1187953787);
@@ -82,14 +76,9 @@ class Arguments extends \ArrayObject
     }
 
     /**
-     * Unsets an argument
-     *
-     * @param mixed $offset Offset
-     * @todo Set parameter type for $offset to mixed or correct union type as breaking change in v12.
-     * @todo Set return type to void as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @param mixed $offset
      */
-    #[\ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         $translatedOffset = $this->translateToLongArgumentName($offset);
         parent::offsetUnset($translatedOffset);
@@ -100,15 +89,9 @@ class Arguments extends \ArrayObject
     }
 
     /**
-     * Returns whether the requested index exists
-     *
-     * @param mixed $offset Offset
-     * @return bool
-     * @todo Set parameter type for $offset to mixed or correct union type as breaking change in v12.
-     * @todo Set return type to bool as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @param mixed $offset
      */
-    #[\ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         $translatedOffset = $this->translateToLongArgumentName($offset);
         return parent::offsetExists($translatedOffset);
@@ -119,12 +102,9 @@ class Arguments extends \ArrayObject
      *
      * @param mixed $offset Offset
      * @return Argument The requested argument object
-     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException if the argument does not exist
-     * @todo Set parameter type for $offset to mixed as breaking change in v12.
-     * @todo Set return type to mixed as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @throws NoSuchArgumentException if the argument does not exist
      */
-    #[\ReturnTypeWillChange]
-    public function offsetGet($offset)
+    public function offsetGet($offset): Argument
     {
         $translatedOffset = $this->translateToLongArgumentName($offset);
         if ($translatedOffset === '') {
@@ -172,7 +152,7 @@ class Arguments extends \ArrayObject
      *
      * @param string $argumentName Name of the argument to retrieve
      * @return Argument
-     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException
+     * @throws NoSuchArgumentException
      */
     public function getArgument($argumentName)
     {
diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/LazyLoadingProxy.php b/typo3/sysext/extbase/Classes/Persistence/Generic/LazyLoadingProxy.php
index be3d2b663014..4498b5926ba4 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/LazyLoadingProxy.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/LazyLoadingProxy.php
@@ -193,7 +193,7 @@ class LazyLoadingProxy implements \Iterator, LoadingStrategyInterface
      * Returns the current value of the storage array
      *
      * @return mixed
-     * @todo Set return type to mixed as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function current()
@@ -205,7 +205,7 @@ class LazyLoadingProxy implements \Iterator, LoadingStrategyInterface
 
     /**
      * Returns the current key storage array
-     * @todo Set return type to int as breaking change in v12 and remove #[\ReturnTypeWillChange].
+     * @todo: Set return type to mixed in v13
      * @return int
      */
     #[\ReturnTypeWillChange]
@@ -218,10 +218,8 @@ class LazyLoadingProxy implements \Iterator, LoadingStrategyInterface
 
     /**
      * Returns the next position of the storage array
-     * @todo Set return type to void as breaking change in v12 and remove #[\ReturnTypeWillChange].
      */
-    #[\ReturnTypeWillChange]
-    public function next()
+    public function next(): void
     {
         // todo: make sure next() can be performed on $realInstance
         $realInstance = $this->_loadRealInstance();
@@ -230,10 +228,8 @@ class LazyLoadingProxy implements \Iterator, LoadingStrategyInterface
 
     /**
      * Resets the array pointer of the storage
-     * @todo Set return type to void as breaking change in v12 and remove #[\ReturnTypeWillChange].
      */
-    #[\ReturnTypeWillChange]
-    public function rewind()
+    public function rewind(): void
     {
         // todo: make sure reset() can be performed on $realInstance
         $realInstance = $this->_loadRealInstance();
@@ -242,12 +238,8 @@ class LazyLoadingProxy implements \Iterator, LoadingStrategyInterface
 
     /**
      * Checks if the array pointer of the storage points to a valid position
-     *
-     * @return bool
-     * @todo Set return type to bool as breaking change in v12 and remove #[\ReturnTypeWillChange].
      */
-    #[\ReturnTypeWillChange]
-    public function valid()
+    public function valid(): bool
     {
         return $this->current() !== false;
     }
diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/LazyObjectStorage.php b/typo3/sysext/extbase/Classes/Persistence/Generic/LazyObjectStorage.php
index 1fd56d734474..39f534c55566 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/LazyObjectStorage.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/LazyObjectStorage.php
@@ -182,6 +182,7 @@ class LazyObjectStorage extends ObjectStorage implements LoadingStrategyInterfac
      * @return TEntity|null The object at the current iterator position.
      *
      * @see \TYPO3\CMS\Extbase\Persistence\ObjectStorage::current
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function current()
@@ -235,9 +236,8 @@ class LazyObjectStorage extends ObjectStorage implements LoadingStrategyInterfac
 
     /**
      * @param TEntity $value The object to look for, or its key in the storage.
-     * @return mixed
-     *
      * @see \TYPO3\CMS\Extbase\Persistence\ObjectStorage::offsetGet
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function offsetGet($value)
diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php b/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
index 1dc2b829f546..995ecf634c0a 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/QueryResult.php
@@ -103,10 +103,8 @@ class QueryResult implements QueryResultInterface
      * Returns the number of objects in the result
      *
      * @return int The number of matching objects
-     * @todo Set to return type int as breaking patch in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         if ($this->numberOfResults === null) {
             if (is_array($this->queryResult)) {
@@ -134,13 +132,8 @@ class QueryResult implements QueryResultInterface
      * but it isn't very useful as the offset has to be an integer
      *
      * @param mixed $offset
-     * @return bool
-     * @see ArrayAccess::offsetExists()
-     * @todo Set $offset to mixed type as breaking change in v12.
-     * @todo Set to return type bool as breaking change in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function offsetExists($offset)
+    public function offsetExists($offset): bool
     {
         $this->initialize();
         return isset($this->queryResult[$offset]);
@@ -149,9 +142,7 @@ class QueryResult implements QueryResultInterface
     /**
      * @param mixed $offset
      * @return mixed
-     * @see ArrayAccess::offsetGet()
-     * @todo Set $offset to mixed type as breaking change in v12.
-     * @todo Set return type to ?mixed as breaking patch in v12.
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function offsetGet($offset)
@@ -165,12 +156,8 @@ class QueryResult implements QueryResultInterface
      *
      * @param mixed $offset
      * @param mixed $value
-     * @see ArrayAccess::offsetSet()
-     * @todo Set $offset and $value to mixed type as breaking change in v12.
-     * @todo Set return type to void as breaking patch in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function offsetSet($offset, $value)
+    public function offsetSet($offset, $value): void
     {
         $this->initialize();
         $this->numberOfResults = null;
@@ -181,12 +168,8 @@ class QueryResult implements QueryResultInterface
      * This method has no effect on the persisted objects but only on the result set
      *
      * @param mixed $offset
-     * @see ArrayAccess::offsetUnset()
-     * @todo Set $offset to mixed type as breaking change in v12.
-     * @todo Set return type to void as breaking patch in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function offsetUnset($offset)
+    public function offsetUnset($offset): void
     {
         $this->initialize();
         $this->numberOfResults = null;
@@ -196,7 +179,7 @@ class QueryResult implements QueryResultInterface
     /**
      * @return mixed
      * @see Iterator::current()
-     * @todo Set return type to mixed as breaking patch in v12.
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function current()
@@ -208,7 +191,7 @@ class QueryResult implements QueryResultInterface
     /**
      * @return mixed
      * @see Iterator::key()
-     * @todo Set return type to mixed as breaking patch in v12.
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function key()
@@ -219,10 +202,8 @@ class QueryResult implements QueryResultInterface
 
     /**
      * @see Iterator::next()
-     * @todo Set return type to void as breaking patch in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function next()
+    public function next(): void
     {
         $this->initialize();
         next($this->queryResult);
@@ -230,10 +211,8 @@ class QueryResult implements QueryResultInterface
 
     /**
      * @see Iterator::rewind()
-     * @todo Set return type to void as breaking patch in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function rewind()
+    public function rewind(): void
     {
         $this->initialize();
         reset($this->queryResult);
@@ -242,10 +221,8 @@ class QueryResult implements QueryResultInterface
     /**
      * @return bool
      * @see Iterator::valid()
-     * @todo Set return type to bool as breaking patch in v12.
      */
-    #[\ReturnTypeWillChange]
-    public function valid()
+    public function valid(): bool
     {
         $this->initialize();
         return current($this->queryResult) !== false;
diff --git a/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php b/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php
index 4f9e0db8b439..1e3465fb6ebf 100644
--- a/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php
+++ b/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php
@@ -90,19 +90,15 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
     /**
      * Rewinds the iterator to the first storage element.
      */
-    #[\ReturnTypeWillChange]
-    public function rewind()
+    public function rewind(): void
     {
         reset($this->storage);
     }
 
     /**
      * Checks if the array pointer of the storage points to a valid position.
-     *
-     * @return bool
      */
-    #[\ReturnTypeWillChange]
-    public function valid()
+    public function valid(): bool
     {
         return current($this->storage) !== false;
     }
@@ -114,8 +110,7 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
      *
      * @return string The index corresponding to the position of the iterator.
      */
-    #[\ReturnTypeWillChange]
-    public function key()
+    public function key(): string
     {
         return key($this->storage);
     }
@@ -124,20 +119,19 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
      * Returns the current storage entry.
      *
      * @return TEntity|null The object at the current iterator position.
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function current()
     {
         $item = current($this->storage);
-
         return $item['obj'] ?? null;
     }
 
     /**
      * Moves to the next entry.
      */
-    #[\ReturnTypeWillChange]
-    public function next()
+    public function next(): void
     {
         next($this->storage);
     }
@@ -147,8 +141,7 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
      *
      * @return int The number of objects in the storage.
      */
-    #[\ReturnTypeWillChange]
-    public function count()
+    public function count(): int
     {
         return count($this->storage);
     }
@@ -159,8 +152,7 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
      * @param TEntity $object The object to add.
      * @param mixed $information The data to associate with the object.
      */
-    #[\ReturnTypeWillChange]
-    public function offsetSet($object, $information)
+    public function offsetSet($object, $information): void
     {
         $this->isModified = true;
         $this->storage[spl_object_hash($object)] = ['obj' => $object, 'inf' => $information];
@@ -173,10 +165,8 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
      * Checks whether an object exists in the storage.
      *
      * @param TEntity|int $value The object to look for, or the key in the storage.
-     * @return bool
      */
-    #[\ReturnTypeWillChange]
-    public function offsetExists($value)
+    public function offsetExists($value): bool
     {
         return (is_object($value) && isset($this->storage[spl_object_hash($value)]))
             || (MathUtility::canBeInterpretedAsInteger($value) && isset(array_values($this->storage)[$value]));
@@ -187,8 +177,7 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
      *
      * @param TEntity|int $value The object to remove, or its key in the storage.
      */
-    #[\ReturnTypeWillChange]
-    public function offsetUnset($value)
+    public function offsetUnset($value): void
     {
         $this->isModified = true;
 
@@ -214,6 +203,7 @@ class ObjectStorage implements \Countable, \Iterator, \ArrayAccess, ObjectMonito
      *
      * @param TEntity|int $value The object to look for, or its key in the storage.
      * @return mixed The data associated with an object in the storage, or the object itself if an integer is passed.
+     * @todo: Set return type to mixed in v13
      */
     #[\ReturnTypeWillChange]
     public function offsetGet($value)
diff --git a/typo3/sysext/install/Classes/Controller/MaintenanceController.php b/typo3/sysext/install/Classes/Controller/MaintenanceController.php
index 360cd92a6618..a227b51d451a 100644
--- a/typo3/sysext/install/Classes/Controller/MaintenanceController.php
+++ b/typo3/sysext/install/Classes/Controller/MaintenanceController.php
@@ -111,7 +111,8 @@ class MaintenanceController extends AbstractController
     {
         $this->clearCacheService->clearAll();
         GeneralUtility::makeInstance(OpcodeCacheService::class)->clearAllActive();
-        $messageQueue = (new FlashMessageQueue('install'))->enqueue(
+        $messageQueue = new FlashMessageQueue('install');
+        $messageQueue->enqueue(
             new FlashMessage('Successfully cleared all caches and all available opcode caches.', 'Caches cleared')
         );
         return new JsonResponse([
@@ -488,7 +489,8 @@ class MaintenanceController extends AbstractController
             );
         }
         (new ClearTableService())->clearSelectedTable($table);
-        $messageQueue = (new FlashMessageQueue('install'))->enqueue(
+        $messageQueue = new FlashMessageQueue('install');
+        $messageQueue->enqueue(
             new FlashMessage('The table ' . $table . ' has been cleared.', 'Table cleared')
         );
         return new JsonResponse([
diff --git a/typo3/sysext/install/Classes/Middleware/Maintenance.php b/typo3/sysext/install/Classes/Middleware/Maintenance.php
index de9a3a6afa8f..ef0e6cea9aea 100644
--- a/typo3/sysext/install/Classes/Middleware/Maintenance.php
+++ b/typo3/sysext/install/Classes/Middleware/Maintenance.php
@@ -196,13 +196,15 @@ class Maintenance implements MiddlewareInterface
                 ]);
             } else {
                 if ($password === null || empty($password)) {
-                    $messageQueue = (new FlashMessageQueue('install'))->enqueue(
+                    $messageQueue = new FlashMessageQueue('install');
+                    $messageQueue->enqueue(
                         new FlashMessage('Please enter the install tool password', '', ContextualFeedbackSeverity::ERROR)
                     );
                 } else {
                     $hashInstance = $this->passwordHashFactory->getDefaultHashInstance('BE');
                     $hashedPassword = $hashInstance->getHashedPassword($password);
-                    $messageQueue = (new FlashMessageQueue('install'))->enqueue(
+                    $messageQueue = new FlashMessageQueue('install');
+                    $messageQueue->enqueue(
                         new FlashMessage(
                             'Given password does not match the install tool login password. Calculated hash: ' . $hashedPassword,
                             '',
-- 
GitLab