From 50e3c636e4c62b5ddb6e82f7bd3a217846065378 Mon Sep 17 00:00:00 2001
From: Alexander Schnitzler <git@alexanderschnitzler.de>
Date: Thu, 17 May 2018 11:49:24 +0200
Subject: [PATCH] [!!!][TASK] Remove support for non namespaced classes in
 Extbase

Non-namespaced classes will no longer be respected in Extbase.
This affects all places where Extbase magic happens, like translating
the model name to repository name (and vice versa).

If you still use class names with underscores, especially models,
repositories and controllers you need to act now.

Releases: master
Resolves: #85036
Change-Id: Ide5923159027802e723dff49729bba52a74c2639
Reviewed-on: https://review.typo3.org/56990
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Mathias Brodala <mbrodala@pagemachine.de>
Tested-by: Mathias Brodala <mbrodala@pagemachine.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
---
 .../Classes/Utility/ClassNamingUtility.php    | 38 +++++------
 ...upportForNonNamespacedClassesInExtbase.rst | 39 +++++++++++
 .../Unit/Utility/ClassNamingUtilityTest.php   | 60 -----------------
 .../sysext/extbase/Classes/Core/Bootstrap.php |  3 +
 .../extbase/Classes/Mvc/Cli/Command.php       |  3 +-
 .../Mvc/Controller/AbstractController.php     | 14 ++--
 typo3/sysext/extbase/Classes/Mvc/Request.php  | 64 ++++++-------------
 .../Generic/Mapper/DataMapFactory.php         | 17 ++---
 .../Property/PropertyMappingConfiguration.php |  8 ---
 .../Classes/Scheduler/FieldProvider.php       | 22 +++----
 .../Classes/Utility/TypeHandlingUtility.php   |  2 +-
 .../Classes/Validation/ValidatorResolver.php  | 12 ++--
 .../Tests/Unit/Mvc/Cli/CommandTest.php        |  7 +-
 .../Tests/Unit/Mvc/Cli/RequestBuilderTest.php | 28 ++++----
 .../Tests/Unit/Mvc/Cli/RequestTest.php        | 58 +----------------
 .../Mvc/Controller/AbstractControllerTest.php | 13 ----
 .../Mvc/Controller/ActionControllerTest.php   | 56 ----------------
 .../extbase/Tests/Unit/Mvc/RequestTest.php    | 18 ------
 .../Fixture/Domain/Model/Entity.php           | 21 ++++++
 .../Domain/Repository/EntityRepository.php    | 21 ++++++
 .../Generic/Mapper/DataMapFactoryTest.php     |  2 -
 .../Tests/Unit/Persistence/RepositoryTest.php | 40 +++---------
 .../Unit/Scheduler/FieldProviderTest.php      | 11 +---
 .../Validation/ValidatorResolverTest.php      |  9 ---
 .../Controller/DownloadControllerTest.php     | 14 +++-
 .../UploadExtensionFileControllerTest.php     | 19 ++++--
 .../Widget/AbstractWidgetControllerTest.php   | 31 +++++++--
 27 files changed, 222 insertions(+), 408 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Breaking-85036-RemoveSupportForNonNamespacedClassesInExtbase.rst
 create mode 100644 typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Model/Entity.php
 create mode 100644 typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Repository/EntityRepository.php

diff --git a/typo3/sysext/core/Classes/Utility/ClassNamingUtility.php b/typo3/sysext/core/Classes/Utility/ClassNamingUtility.php
index 9ba293045ef0..629c49f1fd7b 100644
--- a/typo3/sysext/core/Classes/Utility/ClassNamingUtility.php
+++ b/typo3/sysext/core/Classes/Utility/ClassNamingUtility.php
@@ -34,8 +34,8 @@ class ClassNamingUtility
     public static function translateModelNameToRepositoryName($modelName)
     {
         return str_replace(
-            ['\\Domain\\Model', '_Domain_Model_'],
-            ['\\Domain\\Repository', '_Domain_Repository_'],
+            '\\Domain\\Model',
+            '\\Domain\\Repository',
             $modelName
         ) . 'Repository';
     }
@@ -51,8 +51,8 @@ class ClassNamingUtility
     public static function translateModelNameToValidatorName($modelName)
     {
         return str_replace(
-            ['\\Domain\\Model\\', '_Domain_Model_'],
-            ['\\Domain\\Validator\\', '_Domain_Validator_'],
+            '\\Domain\\Model\\',
+            '\\Domain\\Validator\\',
             $modelName
         ) . 'Validator';
     }
@@ -68,8 +68,8 @@ class ClassNamingUtility
     public static function translateRepositoryNameToModelName($repositoryName)
     {
         return preg_replace(
-            ['/\\\\Domain\\\\Repository/', '/_Domain_Repository_/', '/Repository$/'],
-            ['\\Domain\\Model', '_Domain_Model_', ''],
+            ['/\\\\Domain\\\\Repository/', '/Repository$/'],
+            ['\\Domain\\Model', ''],
             $repositoryName
         );
     }
@@ -85,26 +85,18 @@ class ClassNamingUtility
     {
         $matches = [];
 
-        if (strpos($controllerObjectName, '\\') !== false) {
-            if (substr($controllerObjectName, 0, 9) === 'TYPO3\\CMS') {
-                $extensionName = '^(?P<vendorName>[^\\\\]+\\\[^\\\\]+)\\\(?P<extensionName>[^\\\\]+)';
-            } else {
-                $extensionName = '^(?P<vendorName>[^\\\\]+)\\\\(?P<extensionName>[^\\\\]+)';
-            }
-
-            preg_match(
-                '/' . $extensionName . '\\\\(Controller|Command|(?P<subpackageKey>.+)\\\\Controller)\\\\(?P<controllerName>[a-z\\\\]+)Controller$/ix',
-                $controllerObjectName,
-                $matches
-            );
+        if (substr($controllerObjectName, 0, 9) === 'TYPO3\\CMS') {
+            $extensionName = '^(?P<vendorName>[^\\\\]+\\\[^\\\\]+)\\\(?P<extensionName>[^\\\\]+)';
         } else {
-            preg_match(
-                '/^Tx_(?P<extensionName>[^_]+)_(Controller|Command|(?P<subpackageKey>.+)_Controller)_(?P<controllerName>[a-z_]+)Controller$/ix',
-                $controllerObjectName,
-                $matches
-            );
+            $extensionName = '^(?P<vendorName>[^\\\\]+)\\\\(?P<extensionName>[^\\\\]+)';
         }
 
+        preg_match(
+            '/' . $extensionName . '\\\\(Controller|Command|(?P<subpackageKey>.+)\\\\Controller)\\\\(?P<controllerName>[a-z\\\\]+)Controller$/ix',
+            $controllerObjectName,
+            $matches
+        );
+
         return array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
     }
 }
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-85036-RemoveSupportForNonNamespacedClassesInExtbase.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-85036-RemoveSupportForNonNamespacedClassesInExtbase.rst
new file mode 100644
index 000000000000..1eaf3ea737c2
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-85036-RemoveSupportForNonNamespacedClassesInExtbase.rst
@@ -0,0 +1,39 @@
+.. include:: ../../Includes.txt
+
+========================================================================
+Breaking: #85036 - Removed support for non-namespaced classes in Extbase
+========================================================================
+
+See :issue:`85036`
+
+Description
+===========
+
+Non-namespaced classes like :php:`Tx_Extension_Controller_FooController` are not supported any more
+and all magic based on class names no longer works with classes like these:
+
+* Translating model name to repository name (and vice versa)
+* Translating model name to validator name
+* Guessing the extension name
+* Guessing the controller name by looking at a command name
+* Translating model name to (database) table name
+* Recognizing child property types in object storage annotations
+
+Impact
+======
+
+All this magic no longer works with non-namespaced classes.
+
+
+Affected Installations
+======================
+
+All installations that still use non-namespaced classes in Extbase.
+
+
+Migration
+=========
+
+Use namespaced class names for Extbase.
+
+.. index:: NotScanned, ext:extbase
diff --git a/typo3/sysext/core/Tests/Unit/Utility/ClassNamingUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/ClassNamingUtilityTest.php
index d0c813799c6f..0baff2831479 100644
--- a/typo3/sysext/core/Tests/Unit/Utility/ClassNamingUtilityTest.php
+++ b/typo3/sysext/core/Tests/Unit/Utility/ClassNamingUtilityTest.php
@@ -34,41 +34,6 @@ class ClassNamingUtilityTest extends UnitTestCase
     public function repositoryAndModelClassNames(): array
     {
         return [
-            [
-                'Tx_BlogExample_Domain_Repository_BlogRepository',
-                'Tx_BlogExample_Domain_Model_Blog',
-                'Tx_BlogExample_Domain_Validator_BlogValidator'
-            ],
-            [
-                ' _Domain_Repository_Content_PageRepository',
-                ' _Domain_Model_Content_Page',
-                ' _Domain_Validator_Content_PageValidator'
-            ],
-            [
-                'Tx_RepositoryExample_Domain_Repository_SomeModelRepository',
-                'Tx_RepositoryExample_Domain_Model_SomeModel',
-                'Tx_RepositoryExample_Domain_Validator_SomeModelValidator'
-            ],
-            [
-                'Tx_RepositoryExample_Domain_Repository_RepositoryRepository',
-                'Tx_RepositoryExample_Domain_Model_Repository',
-                'Tx_RepositoryExample_Domain_Validator_RepositoryValidator'
-            ],
-            [
-                'Tx_Repository_Domain_Repository_RepositoryRepository',
-                'Tx_Repository_Domain_Model_Repository',
-                'Tx_Repository_Domain_Validator_RepositoryValidator'
-            ],
-            [
-                'Tx_ModelCollection_Domain_Repository_ModelRepository',
-                'Tx_ModelCollection_Domain_Model_Model',
-                'Tx_ModelCollection_Domain_Validator_ModelValidator'
-            ],
-            [
-                'Tx_Model_Domain_Repository_ModelRepository',
-                'Tx_Model_Domain_Model_Model',
-                'Tx_Model_Domain_Validator_ModelValidator'
-            ],
             [
                 'VENDOR\\EXT\\Domain\\Repository\\BlogRepository',
                 'VENDOR\\EXT\\Domain\\Model\\Blog',
@@ -208,31 +173,6 @@ class ClassNamingUtilityTest extends UnitTestCase
                     'controllerName' => 'Foo',
                 ]
             ],
-            // Oldschool
-            [
-                'Tx_Ext_Controller_FooController',
-                [
-                    'extensionName' => 'Ext',
-                    'subpackageKey' => '',
-                    'controllerName' => 'Foo',
-                ]
-            ],
-            [
-                'Tx_Ext_Command_FooCommandController',
-                [
-                    'extensionName' => 'Ext',
-                    'subpackageKey' => '',
-                    'controllerName' => 'FooCommand',
-                ]
-            ],
-            [
-                'Tx_Fluid_ViewHelpers_Widget_Controller_PaginateController',
-                [
-                    'extensionName' => 'Fluid',
-                    'subpackageKey' => 'ViewHelpers_Widget',
-                    'controllerName' => 'Paginate',
-                ]
-            ],
         ];
     }
 
diff --git a/typo3/sysext/extbase/Classes/Core/Bootstrap.php b/typo3/sysext/extbase/Classes/Core/Bootstrap.php
index e8b50a24b019..0620f0b20065 100644
--- a/typo3/sysext/extbase/Classes/Core/Bootstrap.php
+++ b/typo3/sysext/extbase/Classes/Core/Bootstrap.php
@@ -64,6 +64,9 @@ class Bootstrap implements \TYPO3\CMS\Extbase\Core\BootstrapInterface
     public function initialize($configuration)
     {
         if (!$this->isInCliMode()) {
+            if (!isset($configuration['vendorName']) || $configuration['vendorName'] === '') {
+                throw new \RuntimeException('Invalid configuration: "vendorName" is not set', 1526629315);
+            }
             if (!isset($configuration['extensionName']) || $configuration['extensionName'] === '') {
                 throw new \RuntimeException('Invalid configuration: "extensionName" is not set', 1290623020);
             }
diff --git a/typo3/sysext/extbase/Classes/Mvc/Cli/Command.php b/typo3/sysext/extbase/Classes/Mvc/Cli/Command.php
index aa3a51e61fee..974d69df3384 100644
--- a/typo3/sysext/extbase/Classes/Mvc/Cli/Command.php
+++ b/typo3/sysext/extbase/Classes/Mvc/Cli/Command.php
@@ -93,8 +93,7 @@ class Command
         $this->controllerClassName = $controllerClassName;
         $this->controllerCommandName = $controllerCommandName;
         $this->controllerCommandMethod = $this->controllerCommandName . 'Command';
-        $delimiter = strpos($controllerClassName, '\\') !== false ? '\\' : '_';
-        $classNameParts = explode($delimiter, $controllerClassName);
+        $classNameParts = explode('\\', $controllerClassName);
         if (isset($classNameParts[0]) && $classNameParts[0] === 'TYPO3' && isset($classNameParts[1]) && $classNameParts[1] === 'CMS') {
             $classNameParts[0] .= '\\' . $classNameParts[1];
             unset($classNameParts[1]);
diff --git a/typo3/sysext/extbase/Classes/Mvc/Controller/AbstractController.php b/typo3/sysext/extbase/Classes/Mvc/Controller/AbstractController.php
index 1a6e9de921f5..1db33d442424 100644
--- a/typo3/sysext/extbase/Classes/Mvc/Controller/AbstractController.php
+++ b/typo3/sysext/extbase/Classes/Mvc/Controller/AbstractController.php
@@ -131,16 +131,12 @@ abstract class AbstractController implements ControllerInterface
     public function __construct()
     {
         $className = static::class;
-        if (strpos($className, '\\') !== false) {
-            $classNameParts = explode('\\', $className, 4);
-            // Skip vendor and product name for core classes
-            if (strpos($className, 'TYPO3\\CMS\\') === 0) {
-                $this->extensionName = $classNameParts[2];
-            } else {
-                $this->extensionName = $classNameParts[1];
-            }
+        $classNameParts = explode('\\', $className, 4);
+        // Skip vendor and product name for core classes
+        if (strpos($className, 'TYPO3\\CMS\\') === 0) {
+            $this->extensionName = $classNameParts[2];
         } else {
-            list(, $this->extensionName) = explode('_', $className);
+            $this->extensionName = $classNameParts[1];
         }
     }
 
diff --git a/typo3/sysext/extbase/Classes/Mvc/Request.php b/typo3/sysext/extbase/Classes/Mvc/Request.php
index ac96ad6019d7..87141f473955 100644
--- a/typo3/sysext/extbase/Classes/Mvc/Request.php
+++ b/typo3/sysext/extbase/Classes/Mvc/Request.php
@@ -25,13 +25,6 @@ class Request implements RequestInterface
 {
     const PATTERN_MATCH_FORMAT = '/^[a-z0-9]{1,5}$/';
 
-    /**
-     * Pattern after which the controller object name is built
-     *
-     * @var string
-     */
-    protected $controllerObjectNamePattern = 'Tx_@extension_@subpackage_Controller_@controllerController';
-
     /**
      * Pattern after which the namespaced controller object name is built
      *
@@ -146,42 +139,24 @@ class Request implements RequestInterface
      */
     public function getControllerObjectName()
     {
-        if (null !== $this->controllerVendorName) {
-            // It's safe to assume a namespaced name as namespaced names have to follow PSR-0
-            $objectName = str_replace(
-                [
-                    '@extension',
-                    '@subpackage',
-                    '@controller',
-                    '@vendor',
-                    '\\\\'
-                ],
-                [
-                    $this->controllerExtensionName,
-                    $this->controllerSubpackageKey,
-                    $this->controllerName,
-                    $this->controllerVendorName,
-                    '\\'
-                ],
-                $this->namespacedControllerObjectNamePattern
-            );
-        } else {
-            $objectName = str_replace(
-                [
-                    '@extension',
-                    '@subpackage',
-                    '@controller',
-                    '__'
-                ],
-                [
-                    $this->controllerExtensionName,
-                    $this->controllerSubpackageKey,
-                    $this->controllerName,
-                    '_'
-                ],
-                $this->controllerObjectNamePattern
-            );
-        }
+        $objectName = str_replace(
+            [
+                '@extension',
+                '@subpackage',
+                '@controller',
+                '@vendor',
+                '\\\\'
+            ],
+            [
+                $this->controllerExtensionName,
+                $this->controllerSubpackageKey,
+                $this->controllerName,
+                $this->controllerVendorName,
+                '\\'
+            ],
+            $this->namespacedControllerObjectNamePattern
+        );
+
         // @todo implement getCaseSensitiveObjectName()
         if ($objectName === false) {
             throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchControllerException('The controller object "' . $objectName . '" does not exist.', 1220884009);
@@ -296,9 +271,6 @@ class Request implements RequestInterface
         if (!is_string($controllerName) && $controllerName !== null) {
             throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException('The controller name must be a valid string, ' . gettype($controllerName) . ' given.', 1187176358);
         }
-        if (strpos($controllerName, '_') !== false) {
-            throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException('The controller name must not contain underscores.', 1217846412);
-        }
         if ($controllerName !== null) {
             $this->controllerName = $controllerName;
         }
diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapFactory.php b/typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapFactory.php
index 65c085153741..63999f03f119 100644
--- a/typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapFactory.php
+++ b/typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapFactory.php
@@ -185,18 +185,15 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface
     protected function resolveTableName($className)
     {
         $className = ltrim($className, '\\');
-        if (strpos($className, '\\') !== false) {
-            $classNameParts = explode('\\', $className);
-            // Skip vendor and product name for core classes
-            if (strpos($className, 'TYPO3\\CMS\\') === 0) {
-                $classPartsToSkip = 2;
-            } else {
-                $classPartsToSkip = 1;
-            }
-            $tableName = 'tx_' . strtolower(implode('_', array_slice($classNameParts, $classPartsToSkip)));
+        $classNameParts = explode('\\', $className);
+        // Skip vendor and product name for core classes
+        if (strpos($className, 'TYPO3\\CMS\\') === 0) {
+            $classPartsToSkip = 2;
         } else {
-            $tableName = strtolower($className);
+            $classPartsToSkip = 1;
         }
+        $tableName = 'tx_' . strtolower(implode('_', array_slice($classNameParts, $classPartsToSkip)));
+
         return $tableName;
     }
 
diff --git a/typo3/sysext/extbase/Classes/Property/PropertyMappingConfiguration.php b/typo3/sysext/extbase/Classes/Property/PropertyMappingConfiguration.php
index 42a17d6e2b4f..3081c4988d0f 100644
--- a/typo3/sysext/extbase/Classes/Property/PropertyMappingConfiguration.php
+++ b/typo3/sysext/extbase/Classes/Property/PropertyMappingConfiguration.php
@@ -21,8 +21,6 @@ namespace TYPO3\CMS\Extbase\Property;
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
 
-use TYPO3\CMS\Core\Core\ClassLoadingInformation;
-
 /**
  * Concrete configuration object for the PropertyMapper.
  *
@@ -303,9 +301,6 @@ class PropertyMappingConfiguration implements PropertyMappingConfigurationInterf
      */
     public function setTypeConverterOptions($typeConverter, array $options)
     {
-        if (strpos($typeConverter, '_') !== false) {
-            $typeConverter = ClassLoadingInformation::getClassNameForAlias($typeConverter);
-        }
         foreach ($this->getTypeConvertersWithParentClasses($typeConverter) as $typeConverter) {
             $this->configuration[$typeConverter] = $options;
         }
@@ -323,9 +318,6 @@ class PropertyMappingConfiguration implements PropertyMappingConfigurationInterf
      */
     public function setTypeConverterOption($typeConverter, $optionKey, $optionValue)
     {
-        if (strpos($typeConverter, '_') !== false) {
-            $typeConverter = ClassLoadingInformation::getClassNameForAlias($typeConverter);
-        }
         foreach ($this->getTypeConvertersWithParentClasses($typeConverter) as $typeConverter) {
             $this->configuration[$typeConverter][$optionKey] = $optionValue;
         }
diff --git a/typo3/sysext/extbase/Classes/Scheduler/FieldProvider.php b/typo3/sysext/extbase/Classes/Scheduler/FieldProvider.php
index f3a639f4a638..aece956952f7 100644
--- a/typo3/sysext/extbase/Classes/Scheduler/FieldProvider.php
+++ b/typo3/sysext/extbase/Classes/Scheduler/FieldProvider.php
@@ -138,22 +138,16 @@ class FieldProvider implements \TYPO3\CMS\Scheduler\AdditionalFieldProviderInter
                 continue;
             }
             $className = $command->getControllerClassName();
-            if (strpos($className, '\\')) {
-                $classNameParts = explode('\\', $className);
-                // Skip vendor and product name for core classes
-                if (strpos($className, 'TYPO3\\CMS\\') === 0) {
-                    $classPartsToSkip = 2;
-                } else {
-                    $classPartsToSkip = 1;
-                }
-                $classNameParts = array_slice($classNameParts, $classPartsToSkip);
-                $extensionName = $classNameParts[0];
-                $controllerName = $classNameParts[2];
+            $classNameParts = explode('\\', $className);
+            // Skip vendor and product name for core classes
+            if (strpos($className, 'TYPO3\\CMS\\') === 0) {
+                $classPartsToSkip = 2;
             } else {
-                $classNameParts = explode('_', $className);
-                $extensionName = $classNameParts[1];
-                $controllerName = $classNameParts[3];
+                $classPartsToSkip = 1;
             }
+            $classNameParts = array_slice($classNameParts, $classPartsToSkip);
+            $extensionName = $classNameParts[0];
+            $controllerName = $classNameParts[2];
             $identifier = $command->getCommandIdentifier();
             $options[$identifier] = $extensionName . ' ' . str_replace('CommandController', '', $controllerName) . ': ' . $command->getControllerCommandName();
         }
diff --git a/typo3/sysext/extbase/Classes/Utility/TypeHandlingUtility.php b/typo3/sysext/extbase/Classes/Utility/TypeHandlingUtility.php
index 9d1c98664f60..b0bdd026e13f 100644
--- a/typo3/sysext/extbase/Classes/Utility/TypeHandlingUtility.php
+++ b/typo3/sysext/extbase/Classes/Utility/TypeHandlingUtility.php
@@ -19,7 +19,7 @@ class TypeHandlingUtility
     /**
      * A property type parse pattern.
      */
-    const PARSE_TYPE_PATTERN = '/^\\\\?(?P<type>integer|int|float|double|boolean|bool|string|DateTime|Tx_[a-zA-Z0-9_]+|[A-Z][a-zA-Z0-9\\\\_]+|object|resource|array|ArrayObject|SplObjectStorage|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage)(?:<\\\\?(?P<elementType>[a-zA-Z0-9\\\\_]+)>)?/';
+    const PARSE_TYPE_PATTERN = '/^\\\\?(?P<type>integer|int|float|double|boolean|bool|string|DateTime|[A-Z][a-zA-Z0-9\\\\]+|object|resource|array|ArrayObject|SplObjectStorage|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage)(?:<\\\\?(?P<elementType>[a-zA-Z0-9\\\\]+)>)?/';
 
     /**
      * A type pattern to detect literal types.
diff --git a/typo3/sysext/extbase/Classes/Validation/ValidatorResolver.php b/typo3/sysext/extbase/Classes/Validation/ValidatorResolver.php
index 8e28b7aff2da..4722fd5ee1a5 100644
--- a/typo3/sysext/extbase/Classes/Validation/ValidatorResolver.php
+++ b/typo3/sysext/extbase/Classes/Validation/ValidatorResolver.php
@@ -28,14 +28,13 @@ class ValidatorResolver implements \TYPO3\CMS\Core\SingletonInterface
 {
     /**
      * Match validator names and options
-     * @todo: adjust [a-z0-9_:.\\\\] once Tx_Extbase_Foo syntax is outdated.
      * @deprecated and will be removed in TYPO3 v10.0.
      *
      * @var string
      */
     const PATTERN_MATCH_VALIDATORS = '/
 			(?:^|,\s*)
-			(?P<validatorName>[a-z0-9_:.\\\\]+)
+			(?P<validatorName>[a-z0-9:.\\\\]+)
 			\s*
 			(?:\(
 				(?P<validatorOptions>(?:\s*[a-z0-9]+\s*=\s*(?:
@@ -182,8 +181,7 @@ class ValidatorResolver implements \TYPO3\CMS\Core\SingletonInterface
                 throw new Exception\InvalidTypeHintException('Missing type information, probably no @param annotation for parameter "$' . $parameterName . '" in ' . $className . '->' . $methodName . '()', 1281962564);
             }
 
-            // @todo: remove check for old underscore model name syntax once it's possible
-            if (strpbrk($methodParameter['type'], '_\\') === false) {
+            if (strpbrk($methodParameter['type'], '\\') === false) {
                 $typeValidator = $this->createValidator($methodParameter['type']);
             } else {
                 $typeValidator = null;
@@ -478,19 +476,17 @@ class ValidatorResolver implements \TYPO3\CMS\Core\SingletonInterface
                     $extensionName = array_pop($extensionNameParts);
                     $vendorName = implode('\\', $extensionNameParts);
                     $possibleClassName = $vendorName . '\\' . $extensionName . '\\Validation\\Validator\\' . $extensionValidatorName;
-                } else {
-                    $possibleClassName = 'Tx_' . $extensionName . '_Validation_Validator_' . $extensionValidatorName;
                 }
             } else {
                 // Shorthand built in
                 $possibleClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->getValidatorType($validatorName);
             }
-        } elseif (strpbrk($validatorName, '_\\') === false) {
+        } elseif (strpbrk($validatorName, '\\') === false) {
             // Shorthand built in
             $possibleClassName = 'TYPO3\\CMS\\Extbase\\Validation\\Validator\\' . $this->getValidatorType($validatorName);
         } else {
             // Full qualified
-            // Tx_MyExt_Validation_Validator_MyValidator or \Acme\Ext\Validation\Validator\FooValidator
+            // Example: \Acme\Ext\Validation\Validator\FooValidator
             $possibleClassName = $validatorName;
             if (!empty($possibleClassName) && $possibleClassName[0] === '\\') {
                 $possibleClassName = substr($possibleClassName, 1);
diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/CommandTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/CommandTest.php
index eb0471690786..22438e2f3594 100644
--- a/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/CommandTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/CommandTest.php
@@ -55,9 +55,10 @@ class CommandTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     public function commandIdentifiers()
     {
         return [
-            ['Tx_ExtensionKey_Command_CacheCommandController', 'flush', 'extension_key:cache:flush'],
-            ['Tx_Ext_Command_CookieCommandController', 'bake', 'ext:cookie:bake'],
-            ['Tx_OtherExtensionKey_Foo_Faa_Fuuum_Command_CoffeeCommandController', 'brew', 'other_extension_key:coffee:brew'],
+
+            ['Tx\ExtensionKey\Command\CacheCommandController', 'flush', 'extension_key:cache:flush'],
+            ['Tx\Ext\Command\CookieCommandController', 'bake', 'ext:cookie:bake'],
+            ['Tx\OtherExtensionKey\Foo\Faa\Fuuum\Command\CoffeeCommandController', 'brew', 'other_extension_key:coffee:brew'],
         ];
     }
 
diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestBuilderTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestBuilderTest.php
index e8df0955b7b4..fb28db9451bd 100644
--- a/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestBuilderTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestBuilderTest.php
@@ -71,7 +71,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $this->mockObjectManager = $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
         $this->mockObjectManager->expects($this->any())->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Cli\Request::class)->will($this->returnValue($this->request));
         $this->mockCommand = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Cli\Command::class);
-        $this->mockCommand->expects($this->any())->method('getControllerClassName')->will($this->returnValue('Tx_SomeExtensionName_Command_DefaultCommandController'));
+        $this->mockCommand->expects($this->any())->method('getControllerClassName')->will($this->returnValue('Tx\\SomeExtensionName\\Command\\DefaultCommandController'));
         $this->mockCommand->expects($this->any())->method('getControllerCommandName')->will($this->returnValue('list'));
         $this->mockCommandManager = $this->createMock(\TYPO3\CMS\Extbase\Mvc\Cli\CommandManager::class);
         $this->mockCommandManager->expects($this->any())->method('getCommandByIdentifier')->with('some_extension_name:default:list')->will($this->returnValue($this->mockCommand));
@@ -93,7 +93,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     {
         $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->will($this->returnValue([]));
         $request = $this->requestBuilder->build('some_extension_name:default:list');
-        $this->assertSame('Tx_SomeExtensionName_Command_DefaultCommandController', $request->getControllerObjectName());
+        $this->assertSame('Tx\\SomeExtensionName\\Command\\DefaultCommandController', $request->getControllerObjectName());
         $this->assertSame('list', $request->getControllerCommandName(), 'The CLI request specifying a package, controller and action name did not return a request object pointing to the expected action.');
     }
 
@@ -128,7 +128,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $methodParameters = [
             'testArgument' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $request = $this->requestBuilder->build('some_extension_name:default:list --test-argument=value');
         $this->assertTrue($request->hasArgument('testArgument'), 'The given "testArgument" was not found in the built request.');
         $this->assertSame($request->getArgument('testArgument'), 'value', 'The "testArgument" had not the given value.');
@@ -145,7 +145,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'testArgument' => ['optional' => false, 'type' => 'string'],
             'testArgument2' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $request = $this->requestBuilder->build('some_extension_name:default:list --test-argument=value --test-argument2=value2');
         $this->assertTrue($request->hasArgument('testArgument'), 'The given "testArgument" was not found in the built request.');
         $this->assertTrue($request->hasArgument('testArgument2'), 'The given "testArgument2" was not found in the built request.');
@@ -166,7 +166,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'testArgument3' => ['optional' => false, 'type' => 'string'],
             'testArgument4' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $request = $this->requestBuilder->build('some_extension_name:default:list --test-argument= value --test-argument2 =value2 --test-argument3 = value3 --test-argument4=value4');
         $this->assertTrue($request->hasArgument('testArgument'), 'The given "testArgument" was not found in the built request.');
         $this->assertTrue($request->hasArgument('testArgument2'), 'The given "testArgument2" was not found in the built request.');
@@ -190,7 +190,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'd' => ['optional' => false, 'type' => 'string'],
             'f' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $request = $this->requestBuilder->build('some_extension_name:default:list -d valued -f=valuef -a = valuea');
         $this->assertTrue($request->hasArgument('d'), 'The given "d" was not found in the built request.');
         $this->assertTrue($request->hasArgument('f'), 'The given "f" was not found in the built request.');
@@ -224,7 +224,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'k' => ['optional' => false, 'type' => 'string'],
             'm' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $request = $this->requestBuilder->build('some_extension_name:default:list --test-argument=value --test-argument2= value2 -k --test-argument-3 = value3 --test-argument4=value4 -f valuef -d=valued -a = valuea -c --testArgument7 --test-argument5 = 5 --test-argument6 -j kjk -m');
         $this->assertTrue($request->hasArgument('testArgument'), 'The given "testArgument" was not found in the built request.');
         $this->assertTrue($request->hasArgument('testArgument2'), 'The given "testArgument2" was not found in the built request.');
@@ -260,7 +260,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'testArgument1' => ['optional' => false, 'type' => 'string'],
             'testArgument2' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->exactly(2))->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->exactly(2))->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $request = $this->requestBuilder->build('some_extension_name:default:list --test-argument1 firstArgumentValue --test-argument2 secondArgumentValue');
         $this->assertSame('firstArgumentValue', $request->getArgument('testArgument1'));
         $this->assertSame('secondArgumentValue', $request->getArgument('testArgument2'));
@@ -280,7 +280,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'argument1' => ['optional' => false, 'type' => 'string'],
             'argument2' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $request = $this->requestBuilder->build('some_extension_name:default:list --some -option=value file1 file2');
         $this->assertSame('list', $request->getControllerCommandName());
         $this->assertTrue($request->getArgument('some'));
@@ -297,7 +297,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'testArgument1' => ['optional' => false, 'type' => 'string'],
             'testArgument2' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $expectedArguments = ['testArgument1' => 'firstArgumentValue', 'testArgument2' => 'secondArgumentValue'];
         $request = $this->requestBuilder->build('some_extension_name:default:list --test-argument1=firstArgumentValue --test-argument2 secondArgumentValue exceedingArgument1');
         $this->assertEquals($expectedArguments, $request->getArguments());
@@ -315,7 +315,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'testArgument1' => ['optional' => false, 'type' => 'string'],
             'testArgument2' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $this->requestBuilder->build('some_extension_name:default:list --test-argument1 firstArgumentValue secondArgumentValue');
     }
 
@@ -330,7 +330,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'requiredArgument1' => ['optional' => false, 'type' => 'string'],
             'requiredArgument2' => ['optional' => false, 'type' => 'string']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $this->requestBuilder->build('some_extension_name:default:list firstArgumentValue --required-argument2 secondArgumentValue');
     }
 
@@ -344,7 +344,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'requiredArgument2' => ['optional' => false, 'type' => 'string'],
             'booleanOption' => ['optional' => true, 'type' => 'boolean']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $expectedArguments = ['requiredArgument1' => 'firstArgumentValue', 'requiredArgument2' => 'secondArgumentValue', 'booleanOption' => true];
         $request = $this->requestBuilder->build('some_extension_name:default:list --booleanOption firstArgumentValue secondArgumentValue');
         $this->assertEquals($expectedArguments, $request->getArguments());
@@ -363,7 +363,7 @@ class RequestBuilderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'b5' => ['optional' => true, 'type' => 'boolean'],
             'b6' => ['optional' => true, 'type' => 'boolean']
         ];
-        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx_SomeExtensionName_Command_DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
+        $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('Tx\\SomeExtensionName\\Command\\DefaultCommandController', 'listCommand')->will($this->returnValue($methodParameters));
         $expectedArguments = ['b1' => true, 'b2' => true, 'b3' => true, 'b4' => false, 'b5' => false, 'b6' => false];
         $request = $this->requestBuilder->build('some_extension_name:default:list --b2 y --b1 1 --b3 true --b4 false --b5 n --b6 0');
         $this->assertEquals($expectedArguments, $request->getArguments());
diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestTest.php
index e4d12fab64b3..a4333c3add07 100644
--- a/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Cli/RequestTest.php
@@ -26,69 +26,13 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Mvc\Cli;
  */
 class RequestTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 {
-    /**
-     * @var \TYPO3\CMS\Extbase\Mvc\Cli\Request|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface
-     */
-    protected $request;
-
-    /**
-     * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
-     */
-    protected $mockObjectManager;
-
-    /**
-     * Sets up this test case
-     */
-    protected function setUp()
-    {
-        $this->request = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Mvc\Cli\Request::class, ['dummy']);
-        $this->mockObjectManager = $this->createMock(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface::class);
-        $this->request->_set('objectManager', $this->mockObjectManager);
-    }
-
-    /**
-     * @test
-     */
-    public function getCommandReturnsTheCommandObjectReflectingTheRequestInformation()
-    {
-        $this->request->setControllerObjectName('Tx_Extbase_Command_CacheCommandController');
-        $this->request->setControllerCommandName('flush');
-        $this->mockObjectManager->expects($this->once())->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Cli\Command::class, 'Tx_Extbase_Command_CacheCommandController', 'flush');
-        $this->request->getCommand();
-    }
-
-    /**
-     * @test
-     */
-    public function setControllerObjectNameAndSetControllerCommandNameUnsetTheBuiltCommandObject()
-    {
-        $this->request->setControllerObjectName('Tx_Extbase_Command_CacheCommandController');
-        $this->request->setControllerCommandName('flush');
-        $this->request->getCommand();
-        $this->request->setControllerObjectName('Tx_SomeExtension_Command_BeerCommandController');
-        $this->request->setControllerCommandName('drink');
-        $this->mockObjectManager->expects($this->once())->method('get')->with(\TYPO3\CMS\Extbase\Mvc\Cli\Command::class, 'Tx_SomeExtension_Command_BeerCommandController', 'drink');
-        $this->request->getCommand();
-    }
-
     /**
      * @test
      */
     public function setControllerObjectNameProperlyResolvesExtensionNameWithNamespaces()
     {
         $mockCliRequest = new \TYPO3\CMS\Extbase\Mvc\Cli\Request;
-        $mockCliRequest->setControllerObjectName(\TYPO3\CMS\Extbase\Command\NamespacedMockCommandController::class);
-
-        $this->assertSame('Extbase', $mockCliRequest->getControllerExtensionName());
-    }
-
-    /**
-     * @test
-     */
-    public function setControllerObjectNameProperlyResolvesExtensionNameWithoutNamespaces()
-    {
-        $mockCliRequest = new \TYPO3\CMS\Extbase\Mvc\Cli\Request;
-        $mockCliRequest->setControllerObjectName('Tx_Extbase_Command_OldschoolMockCommandController');
+        $mockCliRequest->setControllerObjectName('TYPO3\CMS\Extbase\Command\NamespacedMockCommandController');
 
         $this->assertSame('Extbase', $mockCliRequest->getControllerExtensionName());
     }
diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/AbstractControllerTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/AbstractControllerTest.php
index 39009a9fecd2..6ca18b0f077a 100644
--- a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/AbstractControllerTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/AbstractControllerTest.php
@@ -19,19 +19,6 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Mvc\Controller;
  */
 class AbstractControllerTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 {
-    /**
-     * @test
-     */
-    public function constructResolvesExtensionnameFromOldStyle()
-    {
-        $className = $this->getUniqueId('Tx_Extbase_Tests_Fixtures_Controller');
-        eval('class ' . $className . ' extends \\' . \TYPO3\CMS\Extbase\Mvc\Controller\AbstractController::class . ' { function getExtensionName() { return $this->extensionName; } }');
-        $mockController = new $className();
-        $expectedResult = 'Extbase';
-        $actualResult = $mockController->getExtensionName();
-        $this->assertEquals($expectedResult, $actualResult);
-    }
-
     /**
      * @test
      */
diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ActionControllerTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ActionControllerTest.php
index b7f33cb4a9c1..a983469df91c 100644
--- a/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ActionControllerTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Mvc/Controller/ActionControllerTest.php
@@ -20,15 +20,11 @@ use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
 use TYPO3\CMS\Extbase\Mvc\Controller\Arguments;
 use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
-use TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService;
 use TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException;
 use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException;
 use TYPO3\CMS\Extbase\Mvc\Request;
 use TYPO3\CMS\Extbase\Mvc\RequestInterface;
 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
-use TYPO3\CMS\Extbase\Mvc\Web\Request as WebRequest;
-use TYPO3\CMS\Extbase\Mvc\Web\Response;
-use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
 use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
 use TYPO3\CMS\Extbase\Reflection\ReflectionService;
@@ -62,58 +58,6 @@ class ActionControllerTest extends UnitTestCase
      */
     protected $mockMvcPropertyMappingConfigurationService;
 
-    protected function setUp()
-    {
-        $this->actionController = $this->getAccessibleMock(ActionController::class);
-    }
-
-    /**
-     * @test
-     */
-    public function processRequestSticksToSpecifiedSequence()
-    {
-        $mockRequest = $this->createMock(WebRequest::class);
-        $mockRequest->expects($this->once())->method('setDispatched')->with(true);
-        $mockUriBuilder = $this->createMock(UriBuilder::class);
-        $mockUriBuilder->expects($this->once())->method('setRequest')->with($mockRequest);
-        $mockObjectManager = $this->createMock(ObjectManagerInterface::class);
-        $mockObjectManager->expects($this->once())->method('get')->with(UriBuilder::class)->will($this->returnValue($mockUriBuilder));
-        $mockResponse = $this->createMock(Response::class);
-        $configurationService = $this->createMock(MvcPropertyMappingConfigurationService::class);
-        /** @var \TYPO3\CMS\Extbase\Mvc\Controller\ActionController|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface */
-        $mockController = $this->getAccessibleMock(ActionController::class, [
-            'initializeFooAction',
-            'initializeAction',
-            'resolveActionMethodName',
-            'initializeActionMethodArguments',
-            'initializeActionMethodValidators',
-            'mapRequestArgumentsToControllerArguments',
-            'buildControllerContext',
-            'resolveView',
-            'initializeView',
-            'callActionMethod',
-            'checkRequestHash'
-        ], [], '', false);
-        $mockController->_set('objectManager', $mockObjectManager);
-
-        $mockController->expects($this->at(0))->method('resolveActionMethodName')->will($this->returnValue('fooAction'));
-        $mockController->expects($this->at(1))->method('initializeActionMethodArguments');
-        $mockController->expects($this->at(2))->method('initializeActionMethodValidators');
-        $mockController->expects($this->at(3))->method('initializeAction');
-        $mockController->expects($this->at(4))->method('initializeFooAction');
-        $mockController->expects($this->at(5))->method('mapRequestArgumentsToControllerArguments');
-        $mockController->expects($this->at(6))->method('checkRequestHash');
-        $mockController->expects($this->at(7))->method('buildControllerContext');
-        $mockController->expects($this->at(8))->method('resolveView');
-
-        $mockController->_set('mvcPropertyMappingConfigurationService', $configurationService);
-        $mockController->_set('arguments', new Arguments());
-
-        $mockController->processRequest($mockRequest, $mockResponse);
-        $this->assertSame($mockRequest, $mockController->_get('request'));
-        $this->assertSame($mockResponse, $mockController->_get('response'));
-    }
-
     /**
      * @test
      */
diff --git a/typo3/sysext/extbase/Tests/Unit/Mvc/RequestTest.php b/typo3/sysext/extbase/Tests/Unit/Mvc/RequestTest.php
index 00544a07603a..3d49ce492948 100644
--- a/typo3/sysext/extbase/Tests/Unit/Mvc/RequestTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Mvc/RequestTest.php
@@ -325,24 +325,6 @@ class RequestTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
                 ],
                 'VENDOR\\Ext\\ViewHelpers\\Widget\\Controller\\FooController',
             ],
-            'No vendor, extension, controller given' => [
-                [
-                    'vendorName' => null,
-                    'extensionName' => 'Ext',
-                    'subpackageKey' => '',
-                    'controllerName' => 'Foo',
-                ],
-                'Tx_Ext_Controller_FooController',
-            ],
-            'No vendor, extension, subpackage, controller given' => [
-                [
-                    'vendorName' => null,
-                    'extensionName' => 'Fluid',
-                    'subpackageKey' => 'ViewHelpers_Widget',
-                    'controllerName' => 'Paginate',
-                ],
-                'Tx_Fluid_ViewHelpers_Widget_Controller_PaginateController',
-            ],
         ];
     }
 
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Model/Entity.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Model/Entity.php
new file mode 100644
index 000000000000..39770569178e
--- /dev/null
+++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Model/Entity.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Fixture\Domain\Model;
+
+/*
+ * 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!
+ */
+
+class Entity extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
+{
+}
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Repository/EntityRepository.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Repository/EntityRepository.php
new file mode 100644
index 000000000000..93ca1876ecd3
--- /dev/null
+++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Fixture/Domain/Repository/EntityRepository.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types = 1);
+
+namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Fixture\Domain\Repository;
+
+/*
+ * 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!
+ */
+
+class EntityRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
+{
+}
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php
index 747ce3d29931..d862e339eb8f 100644
--- a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php
@@ -515,8 +515,6 @@ class DataMapFactoryTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'Core classes with namespaces and leading backslash' => [\TYPO3\CMS\Belog\Domain\Model\LogEntry::class, 'tx_belog_domain_model_logentry'],
             'Extension classes' => ['ExtbaseTeam\\BlogExample\\Domain\\Model\\Blog', 'tx_blogexample_domain_model_blog'],
             'Extension classes with namespaces and leading backslash' => ['\\ExtbaseTeam\\BlogExample\\Domain\\Model\\Blog', 'tx_blogexample_domain_model_blog'],
-            'Extension classes without namespace' => ['Tx_News_Domain_Model_News', 'tx_news_domain_model_news'],
-            'Extension classes without namespace but leading slash' => ['\\Tx_News_Domain_Model_News', 'tx_news_domain_model_news'],
         ];
     }
 
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/RepositoryTest.php b/typo3/sysext/extbase/Tests/Unit/Persistence/RepositoryTest.php
index d70d569b8a17..ea38f9547be7 100644
--- a/typo3/sysext/extbase/Tests/Unit/Persistence/RepositoryTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Persistence/RepositoryTest.php
@@ -328,41 +328,19 @@ class RepositoryTest extends UnitTestCase
         $repository->update(new \stdClass());
     }
 
-    /**
-     * dataProvider for createQueryCallsQueryFactoryWithExpectedType
-     *
-     * @return array
-     */
-    public function modelAndRepositoryClassNames()
-    {
-        return [
-            ['Tx_BlogExample_Domain_Repository_BlogRepository', 'Tx_BlogExample_Domain_Model_Blog'],
-            ['_Domain_Repository_Content_PageRepository', '_Domain_Model_Content_Page'],
-            ['Tx_RepositoryExample_Domain_Repository_SomeModelRepository', 'Tx_RepositoryExample_Domain_Model_SomeModel'],
-            ['Tx_RepositoryExample_Domain_Repository_RepositoryRepository', 'Tx_RepositoryExample_Domain_Model_Repository'],
-            ['Tx_Repository_Domain_Repository_RepositoryRepository', 'Tx_Repository_Domain_Model_Repository']
-        ];
-    }
-
     /**
      * @test
-     * @dataProvider modelAndRepositoryClassNames
-     * @param string $repositoryClassName
-     * @param string $modelClassName
      */
-    public function constructSetsObjectTypeFromClassName($repositoryClassName, $modelClassName)
+    public function constructSetsObjectTypeFromClassName()
     {
-        $repositoryClassNameWithNS = __NAMESPACE__ . '\\' . $repositoryClassName;
-        eval('namespace ' . __NAMESPACE__ . '; class ' . $repositoryClassName . ' extends \\TYPO3\\CMS\\Extbase\\Persistence\\Repository {
-			protected function getRepositoryClassName() {
-				return \'' . $repositoryClassName . '\';
-			}
-			public function _getObjectType() {
-				return $this->objectType;
-			}
-		}');
-        $this->repository = new $repositoryClassNameWithNS($this->mockObjectManager);
-        $this->assertEquals($modelClassName, $this->repository->_getObjectType());
+        $repository = new Fixture\Domain\Repository\EntityRepository($this->mockObjectManager);
+
+        $reflectionClass = new \ReflectionClass($repository);
+        $reflectionProperty = $reflectionClass->getProperty('objectType');
+        $reflectionProperty->setAccessible(true);
+        $objectType = $reflectionProperty->getValue($repository);
+
+        $this->assertEquals(Fixture\Domain\Model\Entity::class, $objectType);
     }
 
     /**
diff --git a/typo3/sysext/extbase/Tests/Unit/Scheduler/FieldProviderTest.php b/typo3/sysext/extbase/Tests/Unit/Scheduler/FieldProviderTest.php
index 8a4613684c43..359777a5a8b9 100644
--- a/typo3/sysext/extbase/Tests/Unit/Scheduler/FieldProviderTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Scheduler/FieldProviderTest.php
@@ -49,19 +49,11 @@ class FieldProviderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $command2->expects($this->once())->method('getControllerCommandName')->will($this->returnValue('FuncB'));
         $command2->expects($this->once())->method('getCommandIdentifier')->will($this->returnValue('mypkg:mockb:funcb'));
 
-        /** @var Command|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $command3 */
-        $command3 = $this->getAccessibleMock(Command::class, [], [], '', false);
-        $command3->expects($this->once())->method('isInternal')->will($this->returnValue(false));
-        $command3->expects($this->once())->method('isCliOnly')->will($this->returnValue(false));
-        $command3->expects($this->once())->method('getControllerClassName')->will($this->returnValue('Tx_Extbase_Command_MockCCommandController'));
-        $command3->expects($this->once())->method('getControllerCommandName')->will($this->returnValue('FuncC'));
-        $command3->expects($this->once())->method('getCommandIdentifier')->will($this->returnValue('extbase:mockc:funcc'));
-
         /** @var CommandManager|\PHPUnit_Framework_MockObject_MockObject $commandManager */
         $commandManager = $this->getMockBuilder(CommandManager::class)
             ->setMethods(['getAvailableCommands'])
             ->getMock();
-        $commandManager->expects($this->any())->method('getAvailableCommands')->will($this->returnValue([$command1, $command2, $command3]));
+        $commandManager->expects($this->any())->method('getAvailableCommands')->will($this->returnValue([$command1, $command2]));
 
         /** @var FieldProvider|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $fieldProvider */
         $fieldProvider = $this->getAccessibleMock(
@@ -76,7 +68,6 @@ class FieldProviderTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $actualResult = $fieldProvider->_call('getCommandControllerActionField', []);
         $this->assertContains('<option title="test" value="extbase:mocka:funca">Extbase MockA: FuncA</option>', $actualResult['code']);
         $this->assertContains('<option title="test" value="mypkg:mockb:funcb">Mypkg MockB: FuncB</option>', $actualResult['code']);
-        $this->assertContains('<option title="test" value="extbase:mockc:funcc">Extbase MockC: FuncC</option>', $actualResult['code']);
     }
 
     /**
diff --git a/typo3/sysext/extbase/Tests/UnitDeprecated/Validation/ValidatorResolverTest.php b/typo3/sysext/extbase/Tests/UnitDeprecated/Validation/ValidatorResolverTest.php
index 113dfd921b2b..2fe4b457b180 100644
--- a/typo3/sysext/extbase/Tests/UnitDeprecated/Validation/ValidatorResolverTest.php
+++ b/typo3/sysext/extbase/Tests/UnitDeprecated/Validation/ValidatorResolverTest.php
@@ -226,15 +226,6 @@ class ValidatorResolverTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCa
                     ]
                 ]
             ],
-            [
-                '$var F3_TestPackage_Quux',
-                [
-                    'argumentName' => 'var',
-                    'validators' => [
-                        ['validatorName' => 'F3_TestPackage_Quux', 'validatorOptions' => []]
-                    ]
-                ]
-            ],
             [
                 '$var Baz(Foo="5"), Bar(Quux="123")',
                 [
diff --git a/typo3/sysext/extensionmanager/Tests/Unit/Controller/DownloadControllerTest.php b/typo3/sysext/extensionmanager/Tests/Unit/Controller/DownloadControllerTest.php
index bca9c25cc210..370a3fea5e08 100644
--- a/typo3/sysext/extensionmanager/Tests/Unit/Controller/DownloadControllerTest.php
+++ b/typo3/sysext/extensionmanager/Tests/Unit/Controller/DownloadControllerTest.php
@@ -14,6 +14,8 @@ namespace TYPO3\CMS\Extensionmanager\Tests\Unit\Controller;
  * The TYPO3 project - inspiring people to share!
  */
 
+use PHPUnit\Framework\MockObject\MockObject;
+
 /**
  * Download from TER controller test
  */
@@ -31,13 +33,19 @@ class DownloadControllerTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestC
         $dummyExtension = $this->getMockBuilder(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension::class)->getMock();
         $dummyExtension->expects($this->any())->method('getExtensionKey')->will($this->returnValue($dummyExtensionName));
 
+        /** @var \TYPO3\CMS\Extensionmanager\Utility\DownloadUtility|MockObject $downloadUtilityMock */
         $downloadUtilityMock = $this->getMockBuilder(\TYPO3\CMS\Extensionmanager\Utility\DownloadUtility::class)->getMock();
         $downloadUtilityMock->expects($this->any())->method('setDownloadPath')->willThrowException($dummyException);
 
-        $subject = $this->getAccessibleMock(\TYPO3\CMS\Extensionmanager\Controller\DownloadController::class, ['dummy']);
-        $subject->_set('downloadUtility', $downloadUtilityMock);
+        /** @var \TYPO3\CMS\Extensionmanager\Controller\DownloadController $subject */
+        $subject = new \TYPO3\CMS\Extensionmanager\Controller\DownloadController();
+        $subject->injectDownloadUtility($downloadUtilityMock);
+
+        $reflectionClass = new \ReflectionClass($subject);
+        $reflectionMethod = $reflectionClass->getMethod('installFromTer');
+        $reflectionMethod->setAccessible(true);
 
-        $result = $subject->_call('installFromTer', $dummyExtension);
+        $result = $reflectionMethod->invokeArgs($subject, [$dummyExtension]);
 
         $expectedResult = [
             false,
diff --git a/typo3/sysext/extensionmanager/Tests/Unit/Controller/UploadExtensionFileControllerTest.php b/typo3/sysext/extensionmanager/Tests/Unit/Controller/UploadExtensionFileControllerTest.php
index eb3174f38dfe..2ad61666eb83 100644
--- a/typo3/sysext/extensionmanager/Tests/Unit/Controller/UploadExtensionFileControllerTest.php
+++ b/typo3/sysext/extensionmanager/Tests/Unit/Controller/UploadExtensionFileControllerTest.php
@@ -14,6 +14,8 @@ namespace TYPO3\CMS\Extensionmanager\Tests\Unit\Controller;
  * The TYPO3 project - inspiring people to share!
  */
 
+use PHPUnit\Framework\MockObject\MockObject;
+
 /**
  * Update from TER controller test
  */
@@ -63,7 +65,7 @@ class UploadExtensionFileControllerTest extends \TYPO3\TestingFramework\Core\Uni
      */
     public function getExtensionFromZipFileExtractsExtensionKey($filename, $expectedKey)
     {
-        $fixture = $this->getAccessibleMock(\TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController::class, ['dummy']);
+        /** @var \TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService|MockObject $managementServiceMock */
         $managementServiceMock = $this->getMockBuilder(\TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService::class)
             ->setMethods(['isAvailable'])
             ->disableOriginalConstructor()
@@ -72,12 +74,21 @@ class UploadExtensionFileControllerTest extends \TYPO3\TestingFramework\Core\Uni
             ->method('isAvailable')
             ->with($expectedKey)
             ->will($this->returnValue(false));
-        $fixture->_set('managementService', $managementServiceMock);
+
+        /** @var \TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility|MockObject $fileHandlingUtilityMock */
         $fileHandlingUtilityMock = $this->createMock(\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility::class);
         $fileHandlingUtilityMock->expects($this->once())->method('unzipExtensionFromFile');
-        $fixture->_set('fileHandlingUtility', $fileHandlingUtilityMock);
 
-        $extensionDetails = $fixture->_call('getExtensionFromZipFile', '', $filename);
+        $fixture = new \TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController();
+        $fixture->injectManagementService($managementServiceMock);
+        $fixture->injectFileHandlingUtility($fileHandlingUtilityMock);
+
+        $reflectionClass = new \ReflectionClass($fixture);
+        $reflectionMethod = $reflectionClass->getMethod('getExtensionFromZipFile');
+        $reflectionMethod->setAccessible(true);
+
+        $extensionDetails = $reflectionMethod->invokeArgs($fixture, ['', $filename]);
+
         $this->assertEquals($expectedKey, $extensionDetails['extKey']);
     }
 }
diff --git a/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php b/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php
index ebc6b02260ec..e77524ee1462 100644
--- a/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php
+++ b/typo3/sysext/fluid/Tests/Unit/Core/Widget/AbstractWidgetControllerTest.php
@@ -115,13 +115,30 @@ class AbstractWidgetControllerTest extends \TYPO3\TestingFramework\Core\Unit\Uni
         $view = $this->getAccessibleMock(TemplateView::class, ['getTemplatePaths', 'toArray'], [], '', false);
         $view->expects($this->exactly(2))->method('getTemplatePaths')->willReturn($templatePaths);
 
-        $mock = $this->getAccessibleMock(AbstractWidgetController::class, ['dummy']);
-        $mock->_set('configurationManager', $configurationManager);
-        $mock->_set('controllerContext', $controllerContext);
-        $mock->_set('request', $request);
-        $method = new \ReflectionMethod(AbstractWidgetController::class, 'setViewConfiguration');
-        $method->setAccessible(true);
-        $method->invokeArgs($mock, [$view]);
+        $prophecy = $this->prophesize(AbstractWidgetController::class);
+
+        /** @var AbstractWidgetController $controller */
+        $controller = $prophecy->reveal();
+
+        $reflectionClass = new \ReflectionClass($controller);
+
+        $reflectionProperty = $reflectionClass->getProperty('configurationManager');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($controller, $configurationManager);
+
+        $reflectionProperty = $reflectionClass->getProperty('controllerContext');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($controller, $controllerContext);
+
+        $reflectionProperty = $reflectionClass->getProperty('request');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($controller, $request);
+
+        $reflectionMethod = $reflectionClass->getMethod('setViewConfiguration');
+        $reflectionMethod->setAccessible(true);
+
+        $reflectionMethod->setAccessible(true);
+        $reflectionMethod->invokeArgs($controller, [$view]);
     }
 
     /**
-- 
GitLab