From a642351c51dd931a8064a744866336ad21c3fc6f Mon Sep 17 00:00:00 2001
From: Larry Garfield <larry@garfieldtech.com>
Date: Tue, 26 Jul 2022 12:58:57 -0500
Subject: [PATCH] [TASK] Flesh out type declarations in PropertyMapper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Doing so allows us to remove an unnecessary test, as well.

'mixed' type declarations not included to allow backporting.

Used command:

> ./Build/Scripts/runTests.sh -s phpstanGenerateBaseline

Resolves: #98027
Releases: main
Change-Id: I3c499e557c5d5bc31bf471e577760f4268fa26cc
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75295
Tested-by: Stefan Bürk <stefan@buerk.tech>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
---
 Build/phpstan/phpstan-baseline.neon           |  5 ---
 .../Classes/Property/PropertyMapper.php       | 32 +++++--------------
 .../Property/PropertyMapperTest.php           | 13 --------
 3 files changed, 8 insertions(+), 42 deletions(-)

diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon
index 67eee36d6350..0b8a3b19db86 100644
--- a/Build/phpstan/phpstan-baseline.neon
+++ b/Build/phpstan/phpstan-baseline.neon
@@ -2085,11 +2085,6 @@ parameters:
 			count: 1
 			path: ../../typo3/sysext/extbase/Tests/Functional/Persistence/OperatorTest.php
 
-		-
-			message: "#^Parameter \\#2 \\$targetType of method TYPO3\\\\CMS\\\\Extbase\\\\Property\\\\PropertyMapper\\:\\:convert\\(\\) expects string, null given\\.$#"
-			count: 1
-			path: ../../typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php
-
 		-
 			message: "#^Constructor of an anonymous class has an unused parameter \\$name\\.$#"
 			count: 1
diff --git a/typo3/sysext/extbase/Classes/Property/PropertyMapper.php b/typo3/sysext/extbase/Classes/Property/PropertyMapper.php
index f089d073bd67..5c684cc658ab 100644
--- a/typo3/sysext/extbase/Classes/Property/PropertyMapper.php
+++ b/typo3/sysext/extbase/Classes/Property/PropertyMapper.php
@@ -28,21 +28,16 @@ use TYPO3\CMS\Extbase\Utility\TypeHandlingUtility;
  */
 class PropertyMapper implements SingletonInterface
 {
-    protected TypeConverterRegistry $typeConverterRegistry;
-    protected PropertyMappingConfigurationBuilder $configurationBuilder;
-
     /**
      * A list of property mapping messages (errors, warnings) which have occurred on last mapping.
      */
     protected Result $messages;
 
     public function __construct(
-        TypeConverterRegistry $typeConverterRegistry,
-        PropertyMappingConfigurationBuilder $configurationBuilder
+        protected TypeConverterRegistry $typeConverterRegistry,
+        protected PropertyMappingConfigurationBuilder $configurationBuilder
     ) {
         $this->resetMessages();
-        $this->typeConverterRegistry = $typeConverterRegistry;
-        $this->configurationBuilder = $configurationBuilder;
     }
 
     /**
@@ -54,11 +49,9 @@ class PropertyMapper implements SingletonInterface
      * @throws Exception
      * @return mixed an instance of $targetType
      */
-    public function convert($source, $targetType, PropertyMappingConfigurationInterface $configuration = null)
+    public function convert($source, string $targetType, ?PropertyMappingConfigurationInterface $configuration = null)
     {
-        if ($configuration === null) {
-            $configuration = $this->configurationBuilder->build();
-        }
+        $configuration ??= $this->configurationBuilder->build();
         $currentPropertyPath = [];
         try {
             $result = $this->doMapping($source, $targetType, $configuration, $currentPropertyPath);
@@ -109,7 +102,7 @@ class PropertyMapper implements SingletonInterface
      *
      * @internal since TYPO3 v12.0
      */
-    protected function doMapping($source, $targetType, PropertyMappingConfigurationInterface $configuration, &$currentPropertyPath)
+    protected function doMapping($source, string $targetType, PropertyMappingConfigurationInterface $configuration, array &$currentPropertyPath)
     {
         if (is_object($source)) {
             $targetType = $this->parseCompositeType($targetType);
@@ -118,9 +111,7 @@ class PropertyMapper implements SingletonInterface
             }
         }
 
-        if ($source === null) {
-            $source = '';
-        }
+        $source ??= '';
 
         $typeConverter = $this->findTypeConverter($source, $targetType, $configuration);
         $targetType = $typeConverter->getTargetTypeForSource($source, $targetType, $configuration);
@@ -174,7 +165,7 @@ class PropertyMapper implements SingletonInterface
      *
      * @internal since TYPO3 v12.0
      */
-    protected function findTypeConverter($source, $targetType, PropertyMappingConfigurationInterface $configuration): TypeConverterInterface
+    protected function findTypeConverter($source, string $targetType, PropertyMappingConfigurationInterface $configuration): TypeConverterInterface
     {
         if ($configuration->getTypeConverter() !== null) {
             return $configuration->getTypeConverter();
@@ -182,10 +173,6 @@ class PropertyMapper implements SingletonInterface
 
         $sourceType = $this->determineSourceType($source);
 
-        if (!is_string($targetType)) {
-            throw new Exception\InvalidTargetException('The target type was no string, but of type "' . gettype($targetType) . '"', 1297941727);
-        }
-
         $targetType = $this->parseCompositeType($targetType);
         $targetType = TypeHandlingUtility::normalizeType($targetType);
 
@@ -224,12 +211,9 @@ class PropertyMapper implements SingletonInterface
      * Parse a composite type like \Foo\Collection<\Bar\Entity> into
      * \Foo\Collection
      *
-     * @param string $compositeType
-     * @return string
-     *
      * @internal since TYPO3 v12.0
      */
-    protected function parseCompositeType($compositeType)
+    protected function parseCompositeType(string $compositeType): string
     {
         if (str_contains($compositeType, '<')) {
             $compositeType = substr($compositeType, 0, (int)strpos($compositeType, '<'));
diff --git a/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php b/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php
index 7b6f68ddd54f..87986569da93 100644
--- a/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Property/PropertyMapperTest.php
@@ -88,19 +88,6 @@ class PropertyMapperTest extends FunctionalTestCase
         $propertyMapper->convert(9999, 'boolean');
     }
 
-    /**
-     * @test
-     */
-    public function convertThrowsAnExceptionIfTargetTypeIsNotAString(): void
-    {
-        $this->expectException(\Exception::class);
-        $this->expectExceptionCode(1297759968);
-        $this->expectExceptionMessage('Exception while property mapping at property path "": The target type was no string, but of type "NULL"');
-
-        $propertyMapper = $this->get(PropertyMapper::class);
-        $propertyMapper->convert(9999, null);
-    }
-
     /**
      * @test
      */
-- 
GitLab